I am coming from Java and learning Python, now. I try to understand the concept of class members in Python.
Here is an example program in Java:
class Hello {
int x = 0;
void ex() {
x = 7;
}
public static void main(String args[]) {
Hello h = new Hello();
System.out.println(h.x);
h.ex();
System.out.println(h.x);
} }
That is what I did in Python, following some examples I found:
class Hello:
def __init__(self) :
self.x = 0
def ex(self):
self.x = 7
h = Hello()
print(h.x)
h.ex()
print(h.x)
Both programs return:
0
7
Here are my questions:
Is the Python Code correct?
The programming style of Python appears to me to be more compact, compared to Java. So I am wondering, WHY does Python require the passing of a "self" -- Parameter.
At this point Python seems to be more "complex" than Java. Or is there a way to remove the "self" -- Parameter?
First, your python code is correct.
It's just a matter about how the languages is designed. Java uses a kind of automatic inference of a reference to the object. It can lead sometimes to strange behaviours for non-java experts:
private int a;
public int add(int a, int b){
return a+b; // what a will it use?
}
So, it's why in java there's the keyword this that can be used (but you're not forced) in order to solve that ambiguity.
The python team decided to force to use the word self (or any other word but I will explain later) to avoid that kind of problem. You cannot get rid of it. Though, java is still a more verbose language than python and the keyword self doesn't affect a lot that assumption.
However you're not obliged to use the "self" word as a reference to the current object. You can use any other word that would be the first parameter of your method (but it's a very bad practice).
Here, you can see two references that explain deeply why "self is here to stay":
http://www.programiz.com/article/python-self-why
http://neopythonic.blogspot.be/2008/10/why-explicit-self-has-to-stay.html
So in java the structure is generally
Class
private data (aka the "struct")
public data
constructors (__init__ in python)
functions etc
its very similar in python. same structure just for any functions working with the data you need to put self as an argument. where java it didn't have to take arguments.
Also it seems in python all data is public by default so you don't need to use getters and setters like in java.
personally I find a Python class more of a C-Struct with some added features, where java everything is thrown into a class.
For what's worth you can save a few line of codes when you have many fields, by using a library to remove the boilerplate. For example with pyfields:
from pyfields import field, make_init
class Hello:
x = field(default=0)
y = field()
__init__ = make_init()
h = Hello(y=10)
print((h.x, h.y))
yields
(0, 10)
You can even combine it with autoclass to get several features out of the box:
from autoclass import autoclass
from pyfields import field
#autoclass
class Hello:
x = field(default=0)
y = field()
h = Hello(y=1)
print(h)
assert h == {'x': 0, 'y': 1}
print(dict(h))
yields
Hello(x=0, y=1)
{'x': 0, 'y': 1}
See documentation for details. I'm the author by the way ;)
2.)Python is a high level language. where java is more mid-high im guessing. kind of new to java.
python goes by white space, where java requires more formatting.
3.) the self parameter can be removed. replace with whatever you want to call it.
Related
Suppose I have code that assigns a method to a Runnable, for example:
class C1{
Runnable r;
}
class C2{
void f(){}
}
var c1 = new C1();
var c2 = new C2();
c1.r = c2::f;
I want to write a unit test to assert that r is indeed assigned f, perhaps like this:
assertThat(c1.r).isEqualTo(c2::f); // Error: object is not a functional interface
Casting to Runnable does not help:
expected: ...$$Lambda$302/0x0000000800cd3518#1fe20588
but was : ...$$Lambda$301/0x0000000800c9fac0#77167fb7
In C# I can assign a method to an Action variable this assertion works. What's the equivalent in Java?
I am open to switching from Runnable to some other type, if that helps.
To give some more context: I'm trying to implement event-based decopuling like Arlo Belshee describes here: https://arlobelshee.com/decoupled-design/. Here's my C# implementation for comparison: https://jay.bazuzi.com/Decoupled-Design/
You're out of luck trying to compare lambdas in any sane way. The code may work in C# and other languages, but it's not worth trying to shoehorn it into Java.
I don't know the purpose of this exercise (as in is it just to test the viability of this in Java or if this is a pattern you regularly use), but generally translating from one language to another doesn't make sense unless there's an obvious compatibility. C# may look like Java (for some weird reason, hello J#), but there's a world of difference making many things completely distinct (e.g. async/await, only superficial similarity between LINQ and Java streams, methods not being truly first class objects in Java, and most likely many more as my C# knowledge is very limited).
IMHO the testing in the example was the weirdest part. It gives a low ROI to test microimplementation like that. I'm not sure if that is useful in GUI testing, but just as if you had a solution that involved metaprogramming, you couldn't just implement it in Java.
The thing is that you create a new method reference each time with ::.
Thus
var c1 = new C1();
var c2 = new C2();
Runnable r = c2::F;
c1.R = r;
System.out.println(c1.R == r);
will print true, because you assign and compare with the same runnable.
I have been writing both Java and Python code for some time now. I have noticed, many times, that objects in both languages often have seemingly inconsistent ways to call their methods. Take these Python code snippets for example. (The syntax is not important, just note the way the methods work with the data)
class Foo(object):
def __init__(self, num = 0):
self.num = num
def __str__(self):
return str(self.num)
def addOne(self):
self.num += 1
if __name__ == "__main__":
foo = Foo()
print(foo) # Outputs 0
foo.addOne()
print(foo) # Outputs 1
Versus:
class Bar(object):
def __init__(self, num = 0):
self.num = num
def __str__(self):
return str(num)
def addOne(self):
return Bar(num + 1)
if __name__ == "__main__":
bar = Bar()
print(bar) # Outputs 0
bar.addOne()
print(bar) # Still Outputs 0
bar = bar.addOne()
print(bar) # Now Outputs 1
Both of these examples are very similar, but the Foo class, when you call Foo.addOne(), changes the num variable inside of the class. The Bar class, however, its addOne() method returns a new object with the num variable updated. Which situation is preferable at what times, what do people expect, and does this differ much in between languages?
Java has certain classes that are immutable. You (as a Java developer) can also create such classes. You cannot change the internal state of any object from an immutable class even if you want to (e.g. you cannot add 1 to an Integer object without creating a new Integer object, and you cannot append "a" to a String object without creating a new String object even if you want to).
Now, if a class is not immutable, you're free to take both approaches (change the internal state of the existing instance, or create a new instance). But whichever approach you take, you should document it so that your callers know what to expect. That's how it works in the Java world at least, as far as I'm aware.
Short answer: there's no such convention. As a language, Python combines both object-oriented and functional paradigms. For me personally, the choice which one to pick in each particular case is the most subtile skill for a Python developer.
You should answer lots of questions, e.g. how your object should be used? would it be shared among threads? is performance an issue? what are the conventions of application architecture? Perhaps the answers would later change so be ready for refactoring.
Python is much less restrictive that Java and cannot give any guarantees concerning the state of an object. It can neither make assumptions to perform low-level performance optimisations as Java do. So the definition 'mutable'/'immutable' is a mere convention for Python classes. It's more how we understand the object than a technical feature of the language.
In general case (or in doubt) I'd suggest to follow the POLA principle and stick to common patterns. For example, if your object behaves like a string, return new instance; if like a dictionary, perform in-place modifications. Extreme cases are usually wrong, good Python design uses the best of two worlds.
In python you can do this:
def f():
return 1, 2, 3
(foo, bar, baz) = f()
Is there an equivalent in java?
tl;dr: No, there isn't such a thing in Java.
You can assign initial values to variables like this:
int foo = 1, bar = 2;
But if your want (1, 2, 3) to be the result of a method call, this is not possible in Java. Java does not allow returning multiple values.
Python allows this:
def foo():
return 1, 2, 3
a, b, c = foo()
The main point, why this does not work in Java is, that the left hand side (LHS) of the assignment must be one variable:
Wrapper wrapper = WrapperGenrator.generateWrapper();
You can not assign to a tuple on the LHS as you can in Python.
If you want (1,2,3) to be the result of a method call, you can use an array:
int[] arr = {1,2,3};
I realize this is an old post, but I could point out a way that comes somewhat close to this.
Using the OP's example (This could obviously use multiple types instead of three ints, but I'm going with the original example),
class Trip{ int foo;int bar;int baz;} // After building this class, have your editor create a constructor for you!
public Trip() {
return new Trip(1,2,3);
}
Trip t = f()
Now at this point I realize you haven't actually ASSIGNED this to three local variables (or member variables) as you would have liked, however you do have a local variable you can use as though you had... like:
t.foo * t.bar + t.baz;
The advantages here are that this is quite terse, hardly more work than the python example and safer/clearer/easier to read; as is I'd be really happy with this!
Perhaps more important though is that as you go on you will realize that this mini-class should have been a real class all along since the values are going to be somewhat associated since they are from the same function!
You can change what you have to a real class with simple editor refactors--replace member access with getter/setter, make members private, extract the class into it's own file and you have a full class!
Chances are that you'll eventually figure out that your original function f() should have been a member (or constructor) of this class in the first place!
By the way, the disadvantage is that this will fully trigger some Java programmers that don't understand that rules were meant to be broken--if you have old coders who are insistent on stuff that seems pedantic (rule-obsessed) it's best not to try this because it'll make their head explode (all over you, most likely).
As I noted in this other question, if your goal is specifically to return multiple values from a function, in Java 16+ you can accomplish something similar to this using a record type:
record FooResult(int a, int b, int c) { }
FooResult produceFoo() {
return new FooResult(1, 2, 3);
}
/* ... */
var f = produceFoo();
System.out.println(f.a + "," + f.b + "," + f.c);
This will let you return any set of types, with named fields, at the expense of having to add a line to declare the record. This won't really help with assignments like (i, j) = (j, i) however.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why there is no way to pass by reference in java
Can anybody tell me why exactly Java does not provide C# "out" type feature when dealing with method parameters to pass by reference ?
I mean why would not it allow us to pass primitive data types like boolean for example, pass by reference. I have tried also with wrapper class java.lang.Boolean but still to no avail. It still wont allow me to pass variable by reference.
Is there any specific reason why Java still has not provided us with this even in version 7 ?
Java only has pass by value. This was a decision made when the language was designed.
Why doesn't java support pass by reference like C++
There is exactly one parameter passing mode -- pass by value -- and that helps keep things simple.
-- James Gosling, et al., The Java Programming Language, 4th Edition
If you want you can put your boolean as a member inside a mutable class (you can't use Boolean because it is immutable), and pass a reference to that class. Apache Commons even has a class called MutableBoolean that you can use.
Only the language design team could tell you why, but I believe the reason for not allowing "out" parameters might be something like: If you want a method that calculates two things, what you really want is either two methods, or one method that returns an object. This supposedly leads to better design and more maintainable code.
Note that you if you really want "out parameters" you can easily use arrays of one element. For example:
void div(int a, int b, int[] q, int[] r) {
if (q != null) q[0] = a/b;
if (r != null) r[0] = a%b;
}
// elsewhere:
int[] quotient = new int[1];
int[] remainder = new int[1];
div(4, 3, quotient, remainder);
This is just my opinion but I feel that the designers of Java believed they could simplify programming by eliminating features rather than making them more intuitive and easier to handle.
Short answer is that it's a design decision and there's nothing you can do with passing by reference that you couldn't do with passing object references by value.
As for your particular problem, there are two solutions:
A mutable wrapper class:
final class BooleanRef {
public boolean value;
}
And use it as:
// Function
void changeTheBoolean( BooleanRef b ){
b.value = true;
}
// Call:
BooleanRef b = new BooleanRef();
changeTheBoolean( b );
OR, (more hackish but more lightweight) wrap in an array:
// Function
void changeTheBoolean( boolean[] b ){
b[0] = true;
}
// Call:
boolean[] b = new boolean[1];
changeTheBoolean( b );
I am trying to learn a java-based program, but I am pretty new to java. I am quite confusing on the following two lines of java code. I think my confusion comes from the concepts including “class” and “cast”, but just do not know how to analyze.
For this one
XValidatingObjectCorpus<Classified<CharSequence>> corpus
= new XValidatingObjectCorpus<Classified<CharSequence>>(numFolds);
What is <Classified<CharSequence>> used for in terms of Java programming? How to understand its relationships with XValidatingObjectCorpusand corpus
For the second one
LogisticRegressionClassifier<CharSequence> classifier
= LogisticRegressionClassifier.<CharSequence>train(para1, para2, para3)
How to understand the right side of LogisticRegressionClassifier.<CharSequence>train? What is the difference between LogisticRegressionClassifier.<CharSequence>train and LogisticRegressionClassifier<CharSequence> classifier
?
These are called generics. They tell Java to make an instance of the outer class - either XValidatingObjectCorpus or LogisticRegressionClassifier - using the type of the inner object.
Normally, these are used for lists and arrays, such as ArrayList or HashMap.
What is the relationship between XValidatingObjectCorpus and corpus?
corpus is just a name given to the new XValidatingObjectCorpus object that you make with that statement (hence the = new... part).
What does LogisticRegressionClassifier.<CharSequence>train mean?
I have no idea, really. I suggest looking at the API for that (I think this is the right class).
What is the difference between LogisticRegressionClassifier.<CharSequence>train and LogisticRegressionClassifier<CharSequence> classifier?
You can't really compare these two. The one on the left of the = is the object identifier, and the one on the right is the allocator (probably the wrong word, but it is what it does, kind of).
Together, the two define an instance of LogisticRegressionClassifier, saying to create that type of object, call it classifier, and then give it the value returned by the train() method. Again, look at the API to understand it more.
By the way, these look like wretched examples to be learning Java with. Start with something simple, or at least an easier part of the code. It looks like someone had way too much fun with long names (the API has even longer names). Seriously though, I only just got to fully understanding this, and Java was my main language for quite a while (It gets really confusing when you try and do simple things). Anyways, good luck!
public class Sample<T> { // T implies Generic implementation, T can be substituted with any object.
static <T> Sample<T> train(int par1, int par2, int par3){
return new Sample<T>(); // you are calling the Generic method to return Sample object which works with a particular type of generic object, may it be an Integer or a CharSequence. --> see the main method.
}
public static void main(String ... a)
{
int par1 = 0, par2 = 0, par3 = 1;
// Here you are returning Sample object which works with a sequence of characters.
Sample<CharSequence> sample = Sample.<CharSequence>train(par1, par2, par3);
// Here you are returning Sample object which works with Integer values.
Sample<CharSequence> sample1 = Sample.<Integer>train(par1, par2, par3);
}
}
<Classified<CharSequence>> is a generic parameter.
LogisticRegressionClassifier<CharSequence> is a generic type.
LogisticRegresstionClassifier.<CharSequence>train is a generic method.
Java Generics Tutorial