Python: Access base class "Class variable" in derive class - python

I am trying to access a class variable from the base class in the derived class and I am getting a no AttributeError
class Parent(object):
variable = 'foo'
class Child(Parent):
def do_something(self):
local = self.variable
I tried using it as Parent.variable but that did not work either. I am getting the same error
AttributeError: 'Child' object has no attribute 'Child variable'
How do i resolve this

I'm not sure what you're doing wrong. The code below assumes you have an initialization method, however.
class Parent(object):
variable = 'foo'
class Child(Parent):
def __init__(self):
pass
def do_something(self):
local = self.variable
print(local)
c = Child()
c.do_something()
Output:
foo

The code shown below should work on both Python 2 & 3:
class Parent(object):
variable = 'foo'
class Child(Parent):
def do_something(self):
local = self.variable
c = Child()
print(c.variable) # output "foo"

Related

Get mangled attribute value of a parent class outside of a class

Imagine a parent class which has a mangled attribute, and a child class:
class Foo:
def __init__(self):
self.__is_init = False
async def init(self):
# Some custom logic here, not important
self.__is_init = True
class Bar(Foo):
...
# Create class instance.
bar = Bar()
# How access `__is_init` of the parent class from the child instance?
How can I get a __is_init value from a parent (Foo) class?
Obviously, I can bar._Foo__is_init in this example, but the problem is that class name is dynamic and I need a general purpose solution that will work with any passed class name.
The solution I see now is iterating over parent classes, and building a mangled attribute name dynamically:
from contextlib import suppress
class MangledAttributeError(Exception):
...
def getattr_mangled(object_: object, name: str) -> str:
for cls_ in getattr(object_, "__mro__", None) or object_.__class__.__mro__:
with suppress(AttributeError):
return getattr(object_, f"_{cls_.__name__}{name}")
raise MangledAttributeError(f"{type(object_).__name__} object has no attribute '{name}'")
Checking that this works:
class Foo:
def __init__(self):
self.__is_init = False
async def init(self):
self.__is_init = True
class Bar(Foo):
def __init__(self):
super().__init__()
bar = Bar()
is_init = getattr_mangled(bar, "__is_init")
print(f"is_init: {is_init}") # Will print `False` which is a correct value in this example
class Foo:
def __init__(self):
self.__is_init = False
async def init(self):
self.__is_init = True
class Bar(Foo):
def getattr_mangled(self, attr:str):
for i in self.__dict__.keys():
if attr in i:
return getattr(self,i)
# return self.__dict__[i] #or like this
bar = Bar()
print(bar.getattr_mangled('__is_init')) #False
if there is a need in __init__ in Bar we should of course initiate Foo's init too by: super().__init__()
When Foo's init is run, self namespace already has attribute name we need in the form we need it (like_PARENT_CLASS_NAME__attrname).
And we can just get it from self namespace without even knowing what parent class name is.

python instantiate child instance from parent object

I have an object which is instantiated from parent class(it will b variable at below example code)
and i want to use this object like a child class instance without knowledge about the member variable of parent class
is there any recommendation?
class A:
def __init__(self):
pass # some member variables are assigned
pass
class B(A):
def test(self):
print("test")
pass
b = A()
b.test() # error
You can do this by setting __class__ of b to B. But read this first:
https://stackoverflow.com/a/13280789/6759844
class A:
def __init__(self):
pass # some member variables are assigned
pass
class B(A):
def test(self):
print("test")
pass
b = A()
b.__class__ = B
b.test() # error

How to access instance variable inside #classmethod?

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.

Using super within nested class

I am puzzled with the following error in python 2.7.12
Suppose we have a class definition within a class, something similar to this:
class C(object):
def __init__(self):
print "class C"
class D(object):
def __init__(self):
print "class D"
class A(D):
class B(C):
def __init__(self):
# Strangely here B is "not defined", why?
super(B, self).__init__()
print "class B"
def __init__(self):
super(D, self).__init__()
print "class A"
def do_something(self):
b_class = self.B()
print "b_class within A : {}".format(b_class)
a_class = A()
a_class.do_something()
but if we we extract the definition of class B outside the scope of class A,
everything works well.
Do we need to use "super" differently when called within a nested class? I fail to understand why its usage would be different within or outside the nested class. Any pointers?
The problem is not the subclass or superclass, but the nesting. B itself is not defined, only A.B is.
Note that in Python there is almost never a good reason to nest classes, though.
You need to address B by its full name, A.B:
class C(object):
def __init__(self):
print "class C"
class D(object):
def __init__(self):
print "class D"
class A(D):
class B(C):
def __init__(self):
super(A.B, self).__init__()
print "class B"
def __init__(self):
super(D, self).__init__()
print "class A"
def do_something(self):
b_class = self.B()
print "b_class within A : {}".format(b_class)
>>> a_class = A()
>>> a_class.do_something()
class A
class C
class B
b_class within A : <__main__.B object at 0x7f0cac98cbd0>

Python - Accessing parent members

I'm facing a standstill here while trying to figure out how to have member classes access data from their parent when they are part of an external module.
Basically, this works (the B class can access is parent's methods like so: A.say_hi(A) ):
class A:
def __init__(self):
print("Initializing parent object...")
self.child = self.B()
class B:
def __init__(self):
print("Initializing child...")
A.say_hi(A)
def say_hi(self):
print("A class says hi")
However, this can get pretty messy if classes start getting extra large, so I have been placing my additional classes in files and importing them inline. The problem with that is I can no longer get the member class to access its parent's members and functions if I try to use 'import B.py' when class B is defined within.
Is there any way to get the original behavior without leaving the member class inside the same file as the parent?
Actually in your example you couldn't access instance of A in your class B. And the code A.say_hi(A) does work however is wrong. This has been said in comments to your question.
Here is how you do that if you want to be able to access parent instance:
Module b:
class B(object):
def __init__(self, parent):
self.parent = parent
def say_hi(self):
print 'Child says hi to his parent %s' % (
self.parent.__class__.__name__
)
self.parent.say_hi()
Module a:
from b import B
class A(object):
def __init__(self):
self.b = B(self)
def say_hi(self):
print 'Parent says hi!'
If you pass the object (a) to the class (b), you can call it directly.
class a():
def __init__(self):
print"Made A"
def test(self):
print ">>A Test"
class b():
def __init__(self,parent):
print"Made B"
self.parent = parent
def test(self):
print ">>B Test"
self.parent.test()
a = a()
a.test()
b = b(a)
b.test()

Categories