I want to access a class variable defined in the parent class constructor. Here is the code.
class A(object):
def __init__(self):
x = 0
class B(A):
def __init__(self):
super(B, self).__init__()
def func(self):
print self.x
s = B()
s.func()
This gives me error:
AttributeError: 'B' object has no attribute 'x'
If I try changing the func() to
def func(self):
print x
then I get error:
NameError: global name 'x' is not defined
If I try changing the func() to
def func(self):
print A.x
Then I get the error
AttributeError: type object 'A' has no attribute 'x'
Now I am running out of ideas.. What's the correct way to access that class variable x in the parent class A? Thanks!
NOTE: I am working only on the "class B" part of my project, hence I can't really go modify class A and change the way variables are defined. That's the only constraint.
It must be self.x, not just x:
class A(object):
def __init__(self):
self.x = 0
Just a quick note - even from other methods of A would be the x not accessible:
class A(object):
def __init__(self):
x = 0
def foo(self):
print(self.x) # <- will not work
print(x) # <- will utimately not work
You need to set it as self.x = 0 instead of x = 0 - otherwise it's just a local variable.
If you cannot modify A, what you are trying to do is impossible - there is absolutely no way to access that value, not even with black magic (if your method was called by that method, you could probably do nasty things with the stack to get its value)
Related
I thought that this code would work
class A:
def __init__(self):
self.x = 1
B = self.create_b()
print(B.y)
def create_b(self):
class B:
def __init__(self):
self.y = self.x
return B
A = A()
but I receive the following error
AttributeError: type object 'B' has no attribute 'y'
What am I doing wrong?
You're confusing classes with class instances (not Python modules). In Python class statements are executable and create a callable object that you must then be called to create instance objects of the class that was defined.
Regular methods of a class automatically receive a first argument that's the instance they belong to, and by convention, this argument is usually called self.
Here's what I mean:
class A:
def __init__(self):
self.x = 1
B = self.create_b() # Create B class.
b = B(self) # Create instance of B class passing this instance of A.
print(b.y)
def create_b(self):
class B:
def __init__(self, a_inst):
self.y = a_inst.x
return B
a = A() # -> 1
There are three problems with this code. The first is that since create-b returns a class object, not an instance of the class, B's __init__ was never run. You could solve this with
class A:
def __init__(self):
self.x = 1
B = self.create_b()
b = B()
print(b.y)
def create_b(self):
class B:
def __init__(self):
self.y = self.x
return B
A = A()
The second is that nested classes do not have access to the wrapping method's local namespace like a nested function (closure) would. When attempting self.y = self.x, instances of class B have no special relationship with the instance of A that created them. You could solve this with
class A:
def __init__(self):
self.x = 1
B = self.create_b(self)
b = B()
print(b.y)
def create_b(self):
class B:
def __init__(self, a):
self.y = a.x
return B
A = A()
The third is that python creates a weakref to classes when they are defined that never goes away. Each time you call create_b, you create a small memory leak. You could solve this with
class A:
def __init__(self):
self.x = 1
b = B(self)
print(b.y)
class B:
def __init__(self, a):
self.y = a.x
A = A()
I have two class as below:
class A:
def __init__(self, a):
self.a = a
class B(A):
#classmethod
def good(cls):
return cls.a
a = B('good')
When I run print(a.good())
It shows AttributeError: type object 'B' has no attribute 'a'
How to access a variable from good method?
In no way.
#classmethods do not have access to instances of the class.
Here is the format of my code:
class A(object):
def __init__(self, x, other):
self.other = other
self.x = x
class B(A):
def __init__(self):
# place code here
def something_else(self):
return self.x["foo"]
x is an object which I would like to call, with a subscript later on (in something_else.
I would like only x to be inherited from the parent class.
It is important that other is not inherited, so super().__init__ is not suitable.
I have attempted a workaround by creating a function within class A:
def x(self):
return self.x
so I could call super().x() in class B, but this doesn't work either.
I have attempted calling directly super.x["foo"], and this doesn't work.
How can I achieve what I want in my case?
Thanks!
Variables don't always have to be registered in the __init__ function, if you want x from class A, have a method in A:
def set_x(self, x):
self.x = x
# other stuff
you'll still be able to call set_x from class B as all functions are inherited, from there you can instantiate property x without calling __init__ from A.
I try to get the name of the variable, which I passed to a function.
class A():
def __init__(self):
self.a = 1
class B():
def __init__(self):
self.b = A()
self.c = A()
def doSomething(self, hello):
print(hello)
B().doSomething(B().b)
<__main__.A object at 0x7f67571a3d68>
What I want is that I can identify in the function B().doSomething(), that the variable is b. Is this possible? One restriction is that in the function B().doSomething() only instance variables of B are passed.
For example in peewee (https://github.com/coleifer/peewee), a MySQL ORM in python, they build expressions for filtering like:
B.select().where(B.b == True)
And somehow they are able to identify, that b is passed. Because otherwise the query can not be build properly.
I know they are using static variables in the class, is this maybe the trick?
Thanks for helping! :)
Going by your B().doSomething(B().b) example call I'm going to assume you're attempting to determine if the variable hello is equivalent to the variable b declared on the class B object.
In which case, all you need to do is call the self reference. self refers to the instance of the object that you're working with and every method defined within a class automatically gets reference to the object's self as a method attribute.
Thus, to determine if the the object b variable is equal to the hello parameter all you need to do is if self.b == hello: #do code
B().b is not an instance variable of B; rather, it is an instance variable of A. In your constructor in B, you may have meant self.a to be an instance of B or self.a to be an instance of B. If this is your general idea, you can implement a boolean overloading method to destinguish between the two. In the case of your code, it may be best to create a third class, C, to check what class an attribute that is passed to doSomething belongs to:
class A():
def __init__(self):
self.a = 1
def __bool__(self):
return True
class B():
def __init__(self):
self.b = 1
def __bool__(self):
return False
class C():
def __init__(self):
self.a = A()
self.b = B()
def doSomething(self, hello):
if not hello:
print("instance of a got passed")
else:
print("instance of b got passed")
C().doSomething(C().b)
Output:
instance of b got passed
I have been searching an answer to my question but could not hit the related answer.
Basically i am trying to call a variable from a Class A thats actually GUI to another Class B my code goes like this:
class CLASSA(wx.Frame):
def Method(self):
self.Var = anyvalue
import CLASSA
class CLASSB():
def __init__(self):
self.Var = CLASSA().Method.Var
i have tried as above but its not working out. Isn't it possible to carry out as mentioned ?
At the very least, you need to actually call CLASSA.Method first:
class CLASSB():
def __init__(self):
self.Var = CLASSA().Method().Var
in order for the Var attribute of the CLASSA object to be initialized.
You do not give enough detail to know if Method is necessary. You could, for instance, simply initialize Var in CLASSA.__init__.
# With recommended capitalization
class A(wx.Frame):
def __init__(self):
self.var = any value
class B(object):
def __init__(self):
sef.var = A().var
It's also possible that B should be a subclass of A, in which case B simply inherits var from A:
>>> class B(A):
... pass
>>> print B().var
anyvalue