This question already has answers here:
Accessing attribute from parent class inside child class
(2 answers)
Closed 6 years ago.
class frozen(object) :
isFrozen = False
print 'In base'
class layer(frozen):
print isFrozen
I am trying to understand the inheritance concept in Python, the above lines are a silly example. "print" statement in the parent class is working as I try to create an object of layer class. But it's throwing an error at the "print" statement of the child class. Saying "isFrozen" is not defined.
But, if I comment out the "print" statement in child class, I can create an object of the child class and access "isFrozen" as "layerObject.isFrozen".
So, could anyone please point out my misunderstanding here?
Class body provides a namespace and classes (unlike functions) are parsed when the module is read (import time). Your problem is that you are calling isFrozen of the frozen class without the namespace. Also to take full advantage of inheritance you need an actual class instance which is usually referred to as self:
class Frozen(object):
isFrozen = False
def __init__(self):
print Frozen.isFrozen
print "From Base"
class Layer(Frozen):
def __init__(self):
print self.isFrozen ##this is defined by the parent
print "From subclass"
self.isFrozen = True
print self.isFrozen
In [7]: test_class = Layer()
False
From subclass
True
In [8]: test_class.isFrozen
Out[8]: True
And a RTFM is suggested here as well.
Related
This question already has answers here:
How to get the caller class name inside a function of another class in python?
(6 answers)
Closed 4 years ago.
I am editing some code that is being called by another system that I do not control. This system initializes my class from a few different places. I need to perform different things depending on where my class is called from.
Is there a way I can find where my object is being initialized?
A.py:
class InitializerA:
def calling_function(self):
Called()
class InitializerB:
def calling_function(self):
Called()
B.py:
class Called:
def __init__(self):
# I want to know here whether it is being called by InitializerA or InitializerB
I was able to find the answer by modifying the method given in this question:
How to get the caller class name inside a function of another class in python?
The inspect library helped me inspect the call stack.
You could pass the class initializing it as an parameter to Called i.e:
class class InitializerA:
def calling_function(self):
Called(self.__name__)
class Called:
def __init__(self, initializer):
self.initializer = initializer
This question already has answers here:
Define a method outside of class definition?
(5 answers)
Closed 4 years ago.
Is it possible (preserving all the class functionality) to write the class functions in separate files?
Below is an example:
TestClass.py:
class MyClass():
def __init__(self, param1=1, param2=2, param3=3):
self.param1, self.param2, self.param3 =param1, param2, param3,
def ClassFun1(self, param1=2):
return param1**2/self.param2
TestClass2.py:
def ClassFun2(self, param1=3):
return param1*3/self.param2
Next, following this answer, I compile both files (I am too lazy to use import), create a class variable and try to use ClassFun2:
x=MyClass()
x.myMethod=ClassFun2
x.myMethod(2)
As a result, I get an error, since self in ClassFun2 is treated as a parameter, rather than class itself:
AttributeError: 'int' object has no attribute 'param2'
Is it possible to split class definition into several source files? It is possible in C++ and this is actually very convenient when working as a team.
The variable x is an object of the class, not the class itself. You need to do:
x = MyClass
x.myMethod = ClassFun2
Notice that I didn't put () after MyClass. That returns the class itself, it doesn't return an instance of the class.
Then you need to create an instance to execute the method:
y = MyClass()
y.myMethod(2)
This question already has answers here:
What is the difference between class and instance attributes?
(5 answers)
Closed 5 years ago.
Came across one Python Class and I am finding it hard to understand how and why its working . A simplified example of the class is :
class Test:
def __init__(self):
self.var = 1
otherVar = 2
def myPrinter(self):
print self.__dict__ # Prints {'var': 1}
print self.var
print self.otherVar # Doubt !!
print self.__dict__ # Prints {'var': 1}
ob = Test()
ob.myPrinter()
My doubt is with the self.otherVar call not throwing an error while self.__dict__ does not show reference to otherVar
It's because otherVar is an attribute of the class, while the var you setup in the __init__ is an attribute of the instance.
The otherVar is visible to the instance, because python first tries to get the instance attribute values, if the instance doesn't have it, then it checks its class attributes. If you define a var in both with different values, things may get confusing at first.
Well, do you know that comparison that a class is like a blueprint and the instance is the object built following it, right? So, var is an extra you added while creating the instance.
If you want to see otherVar, do Test.__dict__. It won't show you var, but all the class attributes.
Play a little with it and with time you are going to get used to it. Class attributes may be tricky, but extremely useful.
otherVar is a class member, not instance member, that's why it doesn't show in __dict__.
It appears in self.__class__.__dict__. (this way doesn't work in Python 2.x)
By the way, otherVar member value is shared across all instances and also accessible from type object: Test.otherVar
Example here: https://trinket.io/python3/d245351e58
For a more in depth explanation check here
This question already has answers here:
Why can't you add attributes to object in python? [duplicate]
(2 answers)
Can't set attributes on instance of "object" class
(7 answers)
Closed 9 years ago.
I just realized that:
class A(object): pass
a = A()
a.x = 'whatever'
Works (does not raise an error and creates a new x member).
But this:
a = object()
a.x = 'whatever'
Raises:
AttributeError: 'object' object has no attribute 'x'
While I probably would never use this in real production code, I'm a bit curious about what the reason is for the different behaviors.
Any hints ?
Probably because of __slots__. By default your class have dict of all atributes which can be added to like in your first example. But that behaviour can bi overriden by using slots.
Also, some classes like datetime which are implemented in C also can not be extended with new attributes at runtime.
Workaround for such classes is to do something like :
class MyObject(): # extend that class, here we extend object
pass # add nothing to the class
o = MyObject()
o.x = 'whatever' # works
This question already has answers here:
How to avoid having class data shared among instances?
(7 answers)
Closed 9 years ago.
i just have a puzzling question abou class attributes in python.
consider the following class below:
class A:
__lst = []
def add(self, str):
self.__lst.append(str)
print len(self.__lst)
i tried to make two instances x and y and i got this:
>>> x = A()
>>> x.add('aaa')
1
>>> x.add('bbb')
2
>>> y = A()
>>> y.add('aaa')
3
>>> y.add('bbb')
4
i was expecting that the instance of y will have a separate copy of the list attribute but it seems that the list just gets bigger even if you use another object to add elements to the list. it's simply weird.
can anybody please enlighten me on this matter?
thanks a lot in advance for your help. :-)
If you define an attribute inside of the class body then it will be a class attribute, and it will be shared by all instances. In your code self.__lst is going to be a reference to A.__lst.
To have a separate list for each attribute, define it as self.__lst inside of the __init__() function:
class A(object):
def __init__(self):
self.__lst = []
def add(self, s):
self.__lst.append(s)
print len(self.__lst)
In addition to the change referenced above, I also made some minor modifications so that your code follows some Python best practices: inheriting from object (new-style class) and not using str (or any other built-in name) as a variable name.
Variables declared inside a class but not by means of self are class-level properties (like your __lst). They are equivalent to Java's static. If you want your property to be unique for all instances, you need to declare them via self (i.e., self.__lst).