When are python class properties created - python

class Foo:
bar = 1
......etc.
I know when creation a instance, bar is created before __init__,
I want to know if it is the very first thing to create the bar property when creating
a instance for Foo.
Also, does the bar already exists in memory before any instance is created?

Remember that in Python class is an executable statement (as too are def and import). So the answer to your question is that bar is created when the class statement executes.
Specifically, when a class statement executes, the body of the class is executed in a namespace that is usually just a dict. When the body has finished executing a class object is created with a copy of the resulting dict as the __dict__ attribute for the class.
The dict at this point contains all the names bound inside the class body bar=1 for example, but also any functions that were defined in the class body.
Instances, when they are created, don't get a copy of bar, they just refer back to the class. When you lookup a name on an instance Python looks in both the instance's __dict__ and the class's __dict__.

Those properties are stored in the the __dict__ of the class itself. They never exist on the instance (or rather the instance's __dict__) unless you assign it manually.
For example, if you use self.bar += 1 in a method you'll read the 1 from the class-level variable and assign 2 to the instance-level variable. The next time you run this statement, bar exists on the instance level so you read that 2 and replace it with 3.

State variables will be assigned before the constructor (init). So...
Class Foo:
bar = 1
def __init__(self):
bartwo = 2
would see bar take on a value of 1, before bartwo was assigned, though. My guess is your question is "If I assign a state variable before a constructor, can I use it in the constructor. Yes.

Related

Python memory allocation, when using bound, static or class functions?

I am curious about this: what actually happens to the python objects once that you create a class that contains each one of these functions?
Looking at some example, I see that either the bound, static or class function is in fact creating a class object, which is the one that contains all 3 function.
Is this always true, no matter which function I call? and the parent object class (object in this case, but can be anything I think) is always called, since the constructor in my class is invoking it implicitly?
class myclass(object):
a=1
b=True
def myfunct(self, b)
return (self.a + b)
#staticmethod
def staticfunct(b):
print b
#classmethod
classfunct(cls, b):
cls.a=b
Since it was not clear: what is the lifecycle for this object class, when I use it as following?
from mymodule import myclass
class1 = myclass()
class1.staticfunct(4)
class1.classfunct(3)
class1.myfunct
In the case of static, myclass object get allocated, and then the function is run, but class and bound method are not generated?
In the case of class funciton, it is the same as above?
in the case of the bound function, everything in the class is allocated?
The class statement creates the class. That is an object which has all three functions, but the first (myfunct) is unbound and cannot be called without an instance object of this class.
The instances of this class (in case you create them) will have bound versions of this function and references to the static and the class functions.
So, both the class and the instances have all three functions.
None of these functions create a class object, though. That is done by the class statement. (To be precise: When the interpreter completes the class creation, i. e. the class does not yet exist when the functions inside it are created; mind boggling, but seldom necessary to know.)
If you do not override the __init__() function, it will be inherited and called for each created instance, yes.
Since it was not clear: what is the lifecycle for this object class,
when I use it as following?
from mymodule import myclass
This will create the class, and code for all functions. They will be classmethod, staticmethod, and method (which you can see by using type() on them)
class1 = myclass()
This will create an instance of the class, which has a dictionary and a lot of other stuff. It doesn't do anything to your methods though.
class1.staticfunct(4)
This calls your staticfunct.
class1.classfunct(3)
This calls you classfunct
class1.myfunct
This will create a new object that is a bound myfunct method of class1. It is often useful to bind this to a variable if you are going to be calling it over and over. But this bound method has normal lifetime.
Here is an example you might find illustrative:
>>> class foo(object):
... def bar(self):
... pass
...
>>> x = foo()
>>> x.bar is x.bar
False
Every time you access x.bar, it creates a new bound method object.
And another example showing class methods:
>>> class foo(object):
... #classmethod
... def bar():
... pass
...
>>> foo.bar
<bound method type.bar of <class '__main__.foo'>>
Your class myclass actually has four methods that are important: the three you explicitly coded and the constructor, __init__ which is inherited from object. Only the constructor creates a new instance. So in your code one instance is created, which you have named class1 (a poor choice of name).
myfunctcreates a new integer by adding class1.a to 4. The lifecycle of class1 is not affected, nor are variables class1.a, class1.b, myclass.a or myclass.b.
staticfunct just prints something, and the attributes of myclass and class1 are irrelevant.
classfunct modifies the variable myclass.a. It has no effect on the lifecycle or state of class1.
The variable myclass.b is never used or accessed at all; the variables named b in the individual functions refer to the values passed in the function's arguments.
Additional info added based on the OP's comments:
Except for the basic data types (int, chars, floats, etc) everything in Python is an object. That includes the class itself (a class object), every method (a method object) and every instance you create. Once created each object remains alive until every reference to it disappears; then it is garbage-collected.
So in your example, when the interpreter reaches the end of the class statement body an object named "myclass" exists, and additional objects exist for each of its members (myclass.a, myclass.b, myclass.myfunct, myclass.staticfunct etc.) There is also some overhead for each object; most objects have a member named __dict__ and a few others. When you instantiate an instance of myclass, named "class1", another new object is created. But there are no new method objects created, and no instance variables since you don't have any of those. class1.a is a pseudonym for myclass.a and similarly for the methods.
If you want to get rid of an object, i.e., have it garbage-collected, you need to eliminate all references to it. In the case of global variables you can use the "del" statement for this purpose:
A = myclass()
del A
Will create a new instance and immediately delete it, releasing its resources for garbage collection. Of course you then cannot subsequently use the object, for example print(A) will now give you an exception.

Instance variable in python

I am new in python i read about Instance variable:
A variable that is defined inside a method and belongs only to the
current instance of a class.
So i test it:
Consider this code:
class test:
count=0
def __init__(self):
test.count += 1
I have a class that add count after Instantiation.
I run this:
t1=test()
t1.count=100
and then I create new instance:
t2=test()
t2.count # 2
then create another instance:
t3=test()
t3.count # 3
t2.count # 3
and then :
t1.count # I get 100
My question is why t2 and t3 was update but if change value of instance variable of specific instance the instance 's instance variable was not update?
In t2 and t3, since you haven't defined an instance variable count, referring to, e.g., t2.count looks up the name in the class scope and evaluates to the class variable test.count.
In t1, you've created a completely different instance variable count that just happens to have the same name as the class variable. t1.count therefore returns this instance variable.
Because instance attributes shadow class attributes, but they are independent.
When you try to access t2.count, there is no instance attribute (t2.__dict__ does not have a count key), so Python next looks at type(t2) to see if it can find the attribute there. The class does have such an attribute, so test.count is returned.
t1.count on the other hand finds the instance attribute and returns that. test.count is never considered.

Why do I need to qualify local variables?

In this class:
class MyClass () :
foo = 1
#staticmethod
def bar () :
print MyClass.foo
Why do I need to qualify foo with MyClass? (otherwise I get NameError: global name 'foo' is not defined.
Isn't foo local to the class MyClass?
This is because Python's scope lookup order is LEGB (locals, enclosed function, global, builtin). More details in this answer. Python has an explicit class variable, which is the first argument of the method, typically named self. Normally one would access foo by using self.foo But in this case, the function is a static method, so it does not receive an explicit class variable, so there is no alternative way to access foo. Either remove the reference to foo or remove the #staticmethod decorator from the bar()and add self as the first argument of bar().
You need to do that because the bar function is a static method. This means you can call it without regarding an instance of the containing class. IE you don't have to create an instance of the class to access that function.
You can read more about it - in the documentation
This is called class attribute
which could be accessed directly by MyClass.foo, and owned by the class.
It's not owned by the instances of the class
for self this is instance variable, each instance of a class has a new copy of the variables
Isn't foo local to the class MyClass?
Actually, no. It's local to the class statement's body, which the bar function cannot access. Once the class object created and bound to MyClass, foo becomes an attribute of the class object (just like bar FWIW), but that's namespace, not scope.
Also and FWIW, Python's staticmethod dont access the class itself. If you want a method that needs to access the class, use a classmethod instead.
In Python, the concept of "local variables" really fully exists only in functions. A function (method) inside a class does not have implicit access to the class's (or instance's) scope; you must explicitly specify the object containing the desired attribute, i.e., the class or the instance (by convention passed to the method as self). As to why it was designed that way... you'd have to ask Guido, but the Zen of Python says "explicit is better than implicit" so that might have something to do with it.

difference between <class name>. <var name> and self.<var name> in a python class

I was wondering what was the difference between the Foo.var= user input and self.var= userinput in the 2 classes.
class foo():
var=None
def __init__(self,userinput):
foo.var=userinput
class bar():
var=None
def __init__(self,userinput):
self.var=userinput
foo refers to the class, self refers to the object.
Class members are a property of the class (and thus are shared between all objects of that class), while instance members are a property of the specific object, so a change to an instance member affects only the given object.
When you operate on an object, the members it has are a merge of the class members and the instance members. When two members with the same name are defined, the instance members have the priority.
Thus:
bar sets an instance variable; that change has effect only on the current instance, so if you do:
b=bar(10)
c=bar(20)
you'll see that c.var is 20 and b.var is 10; nothing strange here;
foo sets a class variable, which is common to all the instances; so, if you do:
f=foo(10)
g=foo(20)
you'll see that both f.var and g.var will be 20, because they both actually refer to foo.var, that was last set to 20 in g's constructor;
on the other hand, instance variables shadow class variables; so, if you do
f=foo(10)
g=foo(20)
f.var=30
you'll have g.var==foo.var==20, but f.var==30, since now f.var refers to the instance variable f.var; but, if you do
del f.var
now the instance (f's) attribute var no longer exists, and thus f.var refers again to the class attribute var (thus f.var==g.var==foo.var==20).
Long story short: normally you'll want to use self.var (i.e. instance members); classname.var is only for sharing stuff between all instances of a given class.
I'd like to point to an existing post which explains the difference perfectly in my opinion.
Python: Difference between class and instance attributes
Yes,
In the first instance you are setting the variable for all instances of foo this is because it is a class variable.
In the second case you are only setting the variable for that instance of foo.
For Example:
class pie():
def __init__(self, j):
pie.var = "pies" + str(j)
print (self.var)
def __str__(self):
return self.var
a = pie(1)
b = pie(2)
print (a)
print (b)

Python subclass inheritance

I am trying to build some classes that inherit from a parent class, which contains subclasses that inherit from other parent classes. But when I change attributes in the subclasses in any children, the change affects all child classes. I am looking to avoid having to create instances, as I am using that feature later.
The code below boils down the problem. The final line shows the unexpected result.
class SubclsParent(object):
a = "Hello"
class Parent(object):
class Subcls(SubclsParent):
pass
class Child1(Parent):
pass
class Child2(Parent):
pass
Child1.Subcls.a # Returns "Hello"
Child2.Subcls.a # Returns "Hello"
Child1.Subcls.a = "Goodbye"
Child1.Subcls.a # Returns "Goodbye"
Child2.Subcls.a # Returns "Goodbye" / Should still return "Hello"!
The behaviour you are seeing is exactly what you should expect. When you define a class
>>> class Foo(object): pass
...
you can modify that class -- not instances of it, the class itself -- because the class is just another object, stored in the variable Foo. So, for instance, you can get and set attributes of the class:
>>> Foo.a = 1
>>> Foo.a
1
In other words, the class keyword creates a new type of object and binds the specified name to that object.
Now, if you define a class inside another class (which is a weird thing to do, by the way), that is equivalent to defining a local variable inside the class body. And you know what defining local variables inside the body of a class does: it sets them as class attributes. In other words, variables defined locally are stored on the class object and not on individual instances. Thus,
>>> class Foo(object):
... class Bar(object): pass
...
defines a class Foo with one class attribute, Bar, which happens itself to be a class. There is no subclassing going on here, though -- the classes Foo and Bar are entirely independent. (The behaviour you have achieved could be replicated as follows:
>>> class Foo(object):
... class Bar(object): pass
...
>>> class Foo(object): pass
...
>>> class Bar(object): pass
...
>>> Foo.Bar = Bar
.)
So you are always modifying the same variable! Of course you will change the values you see; you have changed them yourself!
Your problem seems to be that you are somewhat confused between instance and class attributes, which are not the same thing at all.
A class attribute is a variable which is defined over the whole class. That is, any instance of the class will share the same variable. For instance, most methods are class attributes, since you want to call the same methods on every instance (usually). You can also use class attributes for things like global counters (how many times have you instantiated this class?) and other properties which should be shared amongst instances.
An instance attribute is a variable peculiar to an instance of the class. That is, each instance has a different copy of the variable, with possibly-different contents. This is where you store the data in classes -- if you have a Page class, say, you would like the contents attribute to be stored per-instance, since different Pages will of course need different contents.
In your example, you want Child1.Subcls.a and Child2.Subcls.a to be different variables. Naturally, then, they should depend on the instance!
This may be a bit of a leap of faith, but are you trying to implement Java-style interfaces in Python? In other words, are you trying to specify what properties and methods a class should have, without actually defining those properties?
This used to be considered something of a non-Pythonic thing to do, since the prevailing consensus was that you should allow the classes to do whatever they want and catch the exceptions which arise when they don't define a needed property or method. However, recently people have realised that interfaces are actually sometimes a good thing, and new functionality was added to Python to allow this: abstract base classes.
Try this
class SubclsParent(object):
def __init__(self):
self.a = "Hello"
When you define SubclsParent.a directly on the class, you are defining it as static.
When you use Child1.Subcls, python sees there is no Child1.Subcls, and so checks Parent where it finds it and returns it. The same thing happens for Child2.Subcls. As a result, both of those expressions refer to the same class. Child1 and Child2 do not get their own subclasses of it, rather they have access to the original.
*I am looking to avoid having to create instances, as I am using that feature later. *
I don't understand what you mean here.
Your problem is that when you access the attributes you are accessing inherited routines that were created in the parent class, which all refer to the same variable. You can either make those instance variables, or else you can create the attributes in the child classes to get independent attributes.
It may be that what you really want is metaclasses.

Categories

Resources