What is the proper way to access python class variables? - python

Having a class
class A(object):
z = 0
def Func1(self):
return self.z
def Func2(self):
return A.z
Both methods (Func1 and Func2) give the same result and are only included in this artificial example to illustrate the two possible methods of how to address z.
The result of Func* would only differ if an instance would shadow z with something like self.z = None.
What is the proper python way to access the class variable z using the syntax of Func1 or Func2?

I would say that the proper way to get access to the variable is simply:
a_instance.z #instance variable 'z'
A.z #class variable 'z'
No need for Func1 and Func2 here.
As a side note, if you must write Func2, it seems like a classmethod might be appropriate:
#classmethod
def Func2(cls):
return cls.z
As a final note, which version you use within methods (self.z vs. A.z vs. cls.z with classmethod) really depends on how you want your API to behave. Do you want the user to be able to shadow A.z by setting an instance attribute z? If so, then use self.z. If you don't want that shadowing, you can use A.z. Does the method need self? If not, then it's probably a classmethod, etc.

I would usually use self.z, because in case there are subclasses with different values for z it will choose the "right" one. The only reason not to do that is if you know you will always want the A version notwithstanding.
Accessing via self or via a classmethod (see mgilson's answer) also facilitates the creating of mixin classes.

If you don't care about value clobbering and things like that, you're fine with self.z. Otherwise, A.z will undoubtedly evaluate to the class variable. Beware, though, about what would happen if a subclass B redefines z but not Func2:
class B(A):
z = 7
b = B()
b.Func2() # Returns 0, not 7
Which is quite logical, after all. So, if you want to access a class variable in a, somehow, polymorphic way, you can just do one of the following:
self.__class__.z
type(self).z
According to the documentation, the second form does not work with old-style classes, so the first form is usually more comptaible across Python 2.x versions. However, the second form is the safest one for new-style classes and, thus, for Python 3.x, as classes may redefine the __class__ attribute.

Related

Python __init__ second argument [duplicate]

This question already has answers here:
What is the purpose of the `self` parameter? Why is it needed?
(26 answers)
Closed 6 months ago.
When defining a method on a class in Python, it looks something like this:
class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
But in some other languages, such as C#, you have a reference to the object that the method is bound to with the "this" keyword without declaring it as an argument in the method prototype.
Was this an intentional language design decision in Python or are there some implementation details that require the passing of "self" as an argument?
I like to quote Peters' Zen of Python. "Explicit is better than implicit."
In Java and C++, 'this.' can be deduced, except when you have variable names that make it impossible to deduce. So you sometimes need it and sometimes don't.
Python elects to make things like this explicit rather than based on a rule.
Additionally, since nothing is implied or assumed, parts of the implementation are exposed. self.__class__, self.__dict__ and other "internal" structures are available in an obvious way.
It's to minimize the difference between methods and functions. It allows you to easily generate methods in metaclasses, or add methods at runtime to pre-existing classes.
e.g.
>>> class C:
... def foo(self):
... print("Hi!")
...
>>>
>>> def bar(self):
... print("Bork bork bork!")
...
>>>
>>> c = C()
>>> C.bar = bar
>>> c.bar()
Bork bork bork!
>>> c.foo()
Hi!
>>>
It also (as far as I know) makes the implementation of the python runtime easier.
I suggest that one should read Guido van Rossum's blog on this topic - Why explicit self has to stay.
When a method definition is decorated, we don't know whether to automatically give it a 'self' parameter or not: the decorator could turn the function into a static method (which has no 'self'), or a class method (which has a funny kind of self that refers to a class instead of an instance), or it could do something completely different (it's trivial to write a decorator that implements '#classmethod' or '#staticmethod' in pure Python). There's no way without knowing what the decorator does whether to endow the method being defined with an implicit 'self' argument or not.
I reject hacks like special-casing '#classmethod' and '#staticmethod'.
Python doesn't force you on using "self". You can give it whatever name you want. You just have to remember that the first argument in a method definition header is a reference to the object.
Also allows you to do this: (in short, invoking Outer(3).create_inner_class(4)().weird_sum_with_closure_scope(5) will return 12, but will do so in the craziest of ways.
class Outer(object):
def __init__(self, outer_num):
self.outer_num = outer_num
def create_inner_class(outer_self, inner_arg):
class Inner(object):
inner_arg = inner_arg
def weird_sum_with_closure_scope(inner_self, num)
return num + outer_self.outer_num + inner_arg
return Inner
Of course, this is harder to imagine in languages like Java and C#. By making the self reference explicit, you're free to refer to any object by that self reference. Also, such a way of playing with classes at runtime is harder to do in the more static languages - not that's it's necessarily good or bad. It's just that the explicit self allows all this craziness to exist.
Moreover, imagine this: We'd like to customize the behavior of methods (for profiling, or some crazy black magic). This can lead us to think: what if we had a class Method whose behavior we could override or control?
Well here it is:
from functools import partial
class MagicMethod(object):
"""Does black magic when called"""
def __get__(self, obj, obj_type):
# This binds the <other> class instance to the <innocent_self> parameter
# of the method MagicMethod.invoke
return partial(self.invoke, obj)
def invoke(magic_self, innocent_self, *args, **kwargs):
# do black magic here
...
print magic_self, innocent_self, args, kwargs
class InnocentClass(object):
magic_method = MagicMethod()
And now: InnocentClass().magic_method() will act like expected. The method will be bound with the innocent_self parameter to InnocentClass, and with the magic_self to the MagicMethod instance. Weird huh? It's like having 2 keywords this1 and this2 in languages like Java and C#. Magic like this allows frameworks to do stuff that would otherwise be much more verbose.
Again, I don't want to comment on the ethics of this stuff. I just wanted to show things that would be harder to do without an explicit self reference.
I think it has to do with PEP 227:
Names in class scope are not accessible. Names are resolved in the
innermost enclosing function scope. If a class definition occurs in a
chain of nested scopes, the resolution process skips class
definitions. This rule prevents odd interactions between class
attributes and local variable access. If a name binding operation
occurs in a class definition, it creates an attribute on the resulting
class object. To access this variable in a method, or in a function
nested within a method, an attribute reference must be used, either
via self or via the class name.
I think the real reason besides "The Zen of Python" is that Functions are first class citizens in Python.
Which essentially makes them an Object. Now The fundamental issue is if your functions are object as well then, in Object oriented paradigm how would you send messages to Objects when the messages themselves are objects ?
Looks like a chicken egg problem, to reduce this paradox, the only possible way is to either pass a context of execution to methods or detect it. But since python can have nested functions it would be impossible to do so as the context of execution would change for inner functions.
This means the only possible solution is to explicitly pass 'self' (The context of execution).
So i believe it is a implementation problem the Zen came much later.
As explained in self in Python, Demystified
anything like obj.meth(args) becomes Class.meth(obj, args). The calling process is automatic while the receiving process is not (its explicit). This is the reason the first parameter of a function in class must be the object itself.
class Point(object):
def __init__(self,x = 0,y = 0):
self.x = x
self.y = y
def distance(self):
"""Find distance from origin"""
return (self.x**2 + self.y**2) ** 0.5
Invocations:
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
init() defines three parameters but we just passed two (6 and 8). Similarly distance() requires one but zero arguments were passed.
Why is Python not complaining about this argument number mismatch?
Generally, when we call a method with some arguments, the corresponding class function is called by placing the method's object before the first argument. So, anything like obj.meth(args) becomes Class.meth(obj, args). The calling process is automatic while the receiving process is not (its explicit).
This is the reason the first parameter of a function in class must be the object itself. Writing this parameter as self is merely a convention. It is not a keyword and has no special meaning in Python. We could use other names (like this) but I strongly suggest you not to. Using names other than self is frowned upon by most developers and degrades the readability of the code ("Readability counts").
...
In, the first example self.x is an instance attribute whereas x is a local variable. They are not the same and lie in different namespaces.
Self Is Here To Stay
Many have proposed to make self a keyword in Python, like this in C++ and Java. This would eliminate the redundant use of explicit self from the formal parameter list in methods. While this idea seems promising, it's not going to happen. At least not in the near future. The main reason is backward compatibility. Here is a blog from the creator of Python himself explaining why the explicit self has to stay.
The 'self' parameter keeps the current calling object.
class class_name:
class_variable
def method_name(self,arg):
self.var=arg
obj=class_name()
obj.method_name()
here, the self argument holds the object obj. Hence, the statement self.var denotes obj.var
There is also another very simple answer: according to the zen of python, "explicit is better than implicit".

Python: PEP 8 class name as variable

Which is the convention according to PEP 8 for writing variables that identify class names (not instances)?
That is, given two classes, A and B, which of the following statements would be the right one?
target_class = A if some_condition else B
instance = target_class()
or
TargetClass = A if some_condition else B
instance = TargetClass()
As stated in the style guide,
Class Names:
Class names should normally use the CapWords convention.
But also
Method Names and Instance Variables:
Use the function naming rules: lowercase with words separated by underscores as necessary to improve readability.
In my opinion, these two conventions clash and I can't find which one prevails.
In lack of a specific covering of this case in PEP 8, one can make up an argument for both sides of the medal:
One side is: As A and B both are variables as well, but hold a reference to a class, use CamelCase (TargetClass) in this case.
Nothing prevents you from doing
class A: pass
class B: pass
x = A
A = B
B = x
Now A and B point to the respectively other class, so they aren't really fixed to the class.
So A and B have the only responsibility to hold a class (no matter if they have the same name or a different one), and so has TargetClass.
In order to remain unbiased, we as well can argue in the other way: A and B are special in so far as they are created along with their classes, and the classes' internals have the same name. In so far they are kind of "original", any other assignment should be marked special in so far as they are to be seen as a variable and thus in lower_case.
The truth lies, as so often, somewhere in the middle. There are cases where I would go one way, and others where I would go the other way.
Example 1: You pass a class, which maybe should be instantiated, to a method or function:
def create_new_one(cls):
return cls()
class A: pass
class B: pass
print(create_new_one(A))
In this case, cls is clearly of very temporary state and clearly a variable; can be different at every call. So it should be lower_case.
Example 2: Aliasing of a class
class OldAPI: pass
class NewAPI: pass
class ThirdAPI: pass
CurrentAPI = ThirdAPI
In this case, CurrentAPI is to be seen as a kind of alias for the other one and remains constant throughout the program run. Here I would prefer CamelCase.
In case of doubt I would do the same as Python developers. They wrote the PEP-8 after all.
You can consider your line:
target_class = A if some_condition else B
as an in-line form of the pattern:
target_class = target_class_factory()
and there is a well-known example for it in the Python library, the namedtuple, which uses CamelCase.
I personally think that whether the variable you mentioned, which holds a reference to a class, is defined as a temporary variable (for example in a procedure or function) or as a derivation from an existing class in the global spectrum has the most weight in the case of which one to use. So to summarise from the reply above:
If the variable is temporary, e.g. inside a function or used in a single instance in the solving of a problem, it should be lower_case with underscore separation.
If the variable is within the global spectrum, and is defined along with the other classes as an alias or derivation to use to create objects in the body of the program, it should be defined using CamelCase.
I finally found some light in the style guide:
Class Names
[...]
The naming convention for functions may be used instead in cases where the interface is documented and used primarily as a callable.
may be used is not a strong statement, but it covers the case, as the variable was intended to be used as a callable.
So, for general purpose I think that
target_class = A if some_condition else B
instance = target_class()
is better than
TargetClass = A if some_condition else B
instance = TargetClass()

Should I be using "global" or "self." for class scope variables in Python?

Both of these blocks of code work. Is there a "right" way to do this?
class Stuff:
def __init__(self, x = 0):
global globx
globx = x
def inc(self):
return globx + 1
myStuff = Stuff(3)
print myStuff.inc()
Prints "4"
class Stuff:
def __init__(self, x = 0):
self.x = x
def inc(self):
return self.x + 1
myStuff = Stuff(3)
print myStuff.inc()
Also prints "4"
I'm a noob, and I'm working with a lot of variables in a class. Started wondering why I was putting "self." in front of everything in sight.
Thanks for your help!
You should use the second way, then every instance has a separate x
If you use a global variable then you may find you get surprising results when you have more than one instance of Stuff as changing the value of one will affect all the others.
It's normal to have explicit self's all over your Python code. If you try tricks to avoid that you will be making your code difficult to read for other Python programmers (and potentially introducing extra bugs)
There are 2 ways for "class scope variables". One is to use self, this is called instance variable, each instance of a class has its own copy of instance variables; another one is to define variables in the class definition, this could be achieved by:
class Stuff:
globx = 0
def __init__(self, x = 0):
Stuff.globx = x
...
This is called class attribute, which could be accessed directly by Stuff.globx, and owned by the class, not the instances of the class, just like the static variables in Java.
you should never use global statement for a "class scope variable", because it is not. A variable declared as global is in the global scope, e.g. the namespace of the module in which the class is defined.
namespace and related concept is introduced in the Python tutorial here.
Those are very different semantically. self. means it's an instance variable, i.e. each instance has its own. This is propably the most common kind, but not the only one. And then there are class variables, defined at class level (and therefore by the time the class definition is executed) and accessable in class methods. The equivalent to most uses of static methods, and most propably what you want when you need to share stuff between instances (this is perfectly valid, although not automatically teh one and only way for a given problem). You propably want one of those, depending on what you're doing. Really, we can't read your mind and tell you which one fits your problem.
Globals variables are a different story. They're, well, global - everyone has the same one. This is almost never a good idea (for reasons explained on many occasions), but if you're just writing a quick and dirty script and need share something between several places, they can be acceptable.

Setting a lambda function as a property

Consider these two classes:
class Test(int):
difference = property(lambda self: self.__sub__)
class Test2(int):
difference=lambda self: self.__sub__
Is there any difference between these two classes? New: If so, what is the purpose of using the property to store a lambda function that returns another function?
Update: Changed the question to what I should have asked in the first place. Sorry. Even though I can now know the solution from the answers, it would be unfair for me to do a self answer in these circumstances. (without leaving the answer for a few days at least).
Update 2: Sorry, I wasn't clear enough again. The question was about the particular construction, not properties in general.
For Test1, you could use .difference - for Test2, you'd need to use .difference() instead.
As for why you might use it, a potential use would be to replace something that was previously directly stored as a property with a dynamic calculation instead.
For instance, if you used to store property obj.a, but then you expanded your implementation so that it knew instead properties obj.b and obj.c that could be used to calculate a, but could also be used to calculate different things. If you still wanted to provide backwards-compat with things that used the previous object form, you could implement obj.a as a property() that calculated a based on b and c and it'd behave to those older code fragments as it previously did, with no other code modification needed.
Edit: Ah, I see. You are asking why anybody would do exactly the code above. It's not, in fact a question about why to make a lambda or a property at all, it's not a question of the differences between the two examples, and not even why you want to make a property out of a lambda.
Your question is "Why would anybody make a property of a lambda that just returns self.__sub__".
And the answer is: One wouldn't.
Let's assume somebody wants to do this:
>>> foo = MyInt(8)
>>> print foo.difference(7)
1
So he tries to accomplish it by this class:
class MyInt(int):
def difference(self, i):
return self - i
But that's two lines, and since he is a Ruby programmer and believes that good code is code that has few lines of code, he changes it to:
class MyInt(int):
difference = int.__sub__
To save one line of code. But apparently, things are still too easy. He learned in Ruby that a problem is not properly solved unless you use anonymous code blocks, so he will try to use Pythons nearest equivalent, lambdas, for absolutely no reason:
class MyInt(int):
difference=lambda self, i: self - i
All these works. But things are still WAY to uncomplicated, so instead he decides to make things more complex, by not doing the calculation, but returning the sub method:
class MyInt(int):
difference=lambda self: self.__sub__
Ah, but that doesn't work, because he needs to call difference to get the sub-method:
>>> foo = MyInt(8)
>>> print foo.difference()(7)
1
So he makes it a property:
class MyInt(int):
difference=property(lambda self: self.__sub__)
There. Now he has found the maximum complexity to solve a non-problem.
But normal people wouldn't do any of these, but do:
>>> foo = 8
>>> print foo - 7
1
People have given there opinion without analyzing it, it can be better solved by python itself, below is the code to check the difference
import difflib
from pprint import pprint
s1 = """
class Test(int):
difference=property(lambda self: self.__sub__)
"""
s2 = """
class Test(int):
difference=lambda self: self.__sub__
"""
d = difflib.Differ()
print "and the difference is..."
for c in d.compare(s1, s2):
if c[0] in '+-': print c[1:],
and as expected it says
and the difference is...
p r o p e r t y ( )
Yes, in one case difference is a property. If you are asking what a property is, you can see it as a method that gets automatically called.
Yes, in one case difference is a property
Purpose of property can be
1.
To provide get/set hooks while accessing an attribute
e.g. if you used to have class with attribute a, later on you want to do something else when it is set, you can convert that attribute to property without affecting the interface or how users use your class. So in the example below class A and B are exactly same for a user but internally in B you can do many things in get/setX
class A(object):
def __init__(self):
self.x = 0
a = A()
a.x = 1
class B(object):
def __init__(self):
self.x = 0
def getX(self): return self._x
def setX(self, x): self._x = x
x = property(getX, setX)
b = B()
B.x = 1
2.
As implied in 1, property is a better alternative to get/set calls, so instead of getX, setX user uses less verbose self.x and self.x = 1, though personally I never make a property just for getting or setting a attribute, if need arises it can be done later on as shown in #1/
as far as difference in concerned, property provide you with get/set/del for an atribute, but in the example you have given a method(lambda or proper function) can only be used to do one of get/set or del, so you will need three such lambdas differenceSet, differenceGet, differenceDel

Why do you need explicitly have the "self" argument in a Python method? [duplicate]

This question already has answers here:
What is the purpose of the `self` parameter? Why is it needed?
(26 answers)
Closed 6 months ago.
When defining a method on a class in Python, it looks something like this:
class MyClass(object):
def __init__(self, x, y):
self.x = x
self.y = y
But in some other languages, such as C#, you have a reference to the object that the method is bound to with the "this" keyword without declaring it as an argument in the method prototype.
Was this an intentional language design decision in Python or are there some implementation details that require the passing of "self" as an argument?
I like to quote Peters' Zen of Python. "Explicit is better than implicit."
In Java and C++, 'this.' can be deduced, except when you have variable names that make it impossible to deduce. So you sometimes need it and sometimes don't.
Python elects to make things like this explicit rather than based on a rule.
Additionally, since nothing is implied or assumed, parts of the implementation are exposed. self.__class__, self.__dict__ and other "internal" structures are available in an obvious way.
It's to minimize the difference between methods and functions. It allows you to easily generate methods in metaclasses, or add methods at runtime to pre-existing classes.
e.g.
>>> class C:
... def foo(self):
... print("Hi!")
...
>>>
>>> def bar(self):
... print("Bork bork bork!")
...
>>>
>>> c = C()
>>> C.bar = bar
>>> c.bar()
Bork bork bork!
>>> c.foo()
Hi!
>>>
It also (as far as I know) makes the implementation of the python runtime easier.
I suggest that one should read Guido van Rossum's blog on this topic - Why explicit self has to stay.
When a method definition is decorated, we don't know whether to automatically give it a 'self' parameter or not: the decorator could turn the function into a static method (which has no 'self'), or a class method (which has a funny kind of self that refers to a class instead of an instance), or it could do something completely different (it's trivial to write a decorator that implements '#classmethod' or '#staticmethod' in pure Python). There's no way without knowing what the decorator does whether to endow the method being defined with an implicit 'self' argument or not.
I reject hacks like special-casing '#classmethod' and '#staticmethod'.
Python doesn't force you on using "self". You can give it whatever name you want. You just have to remember that the first argument in a method definition header is a reference to the object.
Also allows you to do this: (in short, invoking Outer(3).create_inner_class(4)().weird_sum_with_closure_scope(5) will return 12, but will do so in the craziest of ways.
class Outer(object):
def __init__(self, outer_num):
self.outer_num = outer_num
def create_inner_class(outer_self, inner_arg):
class Inner(object):
inner_arg = inner_arg
def weird_sum_with_closure_scope(inner_self, num)
return num + outer_self.outer_num + inner_arg
return Inner
Of course, this is harder to imagine in languages like Java and C#. By making the self reference explicit, you're free to refer to any object by that self reference. Also, such a way of playing with classes at runtime is harder to do in the more static languages - not that's it's necessarily good or bad. It's just that the explicit self allows all this craziness to exist.
Moreover, imagine this: We'd like to customize the behavior of methods (for profiling, or some crazy black magic). This can lead us to think: what if we had a class Method whose behavior we could override or control?
Well here it is:
from functools import partial
class MagicMethod(object):
"""Does black magic when called"""
def __get__(self, obj, obj_type):
# This binds the <other> class instance to the <innocent_self> parameter
# of the method MagicMethod.invoke
return partial(self.invoke, obj)
def invoke(magic_self, innocent_self, *args, **kwargs):
# do black magic here
...
print magic_self, innocent_self, args, kwargs
class InnocentClass(object):
magic_method = MagicMethod()
And now: InnocentClass().magic_method() will act like expected. The method will be bound with the innocent_self parameter to InnocentClass, and with the magic_self to the MagicMethod instance. Weird huh? It's like having 2 keywords this1 and this2 in languages like Java and C#. Magic like this allows frameworks to do stuff that would otherwise be much more verbose.
Again, I don't want to comment on the ethics of this stuff. I just wanted to show things that would be harder to do without an explicit self reference.
I think it has to do with PEP 227:
Names in class scope are not accessible. Names are resolved in the
innermost enclosing function scope. If a class definition occurs in a
chain of nested scopes, the resolution process skips class
definitions. This rule prevents odd interactions between class
attributes and local variable access. If a name binding operation
occurs in a class definition, it creates an attribute on the resulting
class object. To access this variable in a method, or in a function
nested within a method, an attribute reference must be used, either
via self or via the class name.
I think the real reason besides "The Zen of Python" is that Functions are first class citizens in Python.
Which essentially makes them an Object. Now The fundamental issue is if your functions are object as well then, in Object oriented paradigm how would you send messages to Objects when the messages themselves are objects ?
Looks like a chicken egg problem, to reduce this paradox, the only possible way is to either pass a context of execution to methods or detect it. But since python can have nested functions it would be impossible to do so as the context of execution would change for inner functions.
This means the only possible solution is to explicitly pass 'self' (The context of execution).
So i believe it is a implementation problem the Zen came much later.
As explained in self in Python, Demystified
anything like obj.meth(args) becomes Class.meth(obj, args). The calling process is automatic while the receiving process is not (its explicit). This is the reason the first parameter of a function in class must be the object itself.
class Point(object):
def __init__(self,x = 0,y = 0):
self.x = x
self.y = y
def distance(self):
"""Find distance from origin"""
return (self.x**2 + self.y**2) ** 0.5
Invocations:
>>> p1 = Point(6,8)
>>> p1.distance()
10.0
init() defines three parameters but we just passed two (6 and 8). Similarly distance() requires one but zero arguments were passed.
Why is Python not complaining about this argument number mismatch?
Generally, when we call a method with some arguments, the corresponding class function is called by placing the method's object before the first argument. So, anything like obj.meth(args) becomes Class.meth(obj, args). The calling process is automatic while the receiving process is not (its explicit).
This is the reason the first parameter of a function in class must be the object itself. Writing this parameter as self is merely a convention. It is not a keyword and has no special meaning in Python. We could use other names (like this) but I strongly suggest you not to. Using names other than self is frowned upon by most developers and degrades the readability of the code ("Readability counts").
...
In, the first example self.x is an instance attribute whereas x is a local variable. They are not the same and lie in different namespaces.
Self Is Here To Stay
Many have proposed to make self a keyword in Python, like this in C++ and Java. This would eliminate the redundant use of explicit self from the formal parameter list in methods. While this idea seems promising, it's not going to happen. At least not in the near future. The main reason is backward compatibility. Here is a blog from the creator of Python himself explaining why the explicit self has to stay.
The 'self' parameter keeps the current calling object.
class class_name:
class_variable
def method_name(self,arg):
self.var=arg
obj=class_name()
obj.method_name()
here, the self argument holds the object obj. Hence, the statement self.var denotes obj.var
There is also another very simple answer: according to the zen of python, "explicit is better than implicit".

Categories