Python – reference inner class from other inner class
Question:
I am trying to reference an inner class from another inner class. I have tried both :
class Foo(object):
class A(object):
pass
class B(object):
other = A
and
class Foo(object):
class A(object):
pass
class B(object):
other = Foo.A
with respective results:
Traceback (most recent call last):
File "python", line 1, in <module>
File "python", line 6, in Foo
File "python", line 7, in B
NameError: name 'A' is not defined
and
Traceback (most recent call last):
File "python", line 1, in <module>
File "python", line 6, in Foo
File "python", line 7, in B
NameError: name 'Foo' is not defined
Is this possible?
Answers:
This is not possible, since everything you define in a class becomes a valid member only in an instance of that class, unless you define a method with @staticmethod
, but there is no such property for a class.
So, this won’t work either:
class Foo(object):
x = 10
class A(object):
pass
class B(object):
other = x
This will work, but it is not what you intended:
class Foo(object):
x = 10
class A(object):
pass
class B(object):
def __init__(self):
self.other = Foo.A
f = Foo()
print(f.B().other)
The output is:
<class '__main__.Foo.A'>
The reason this works is that the methods (in this case __init__
) are evaluated when the object is created, while assignment before the __init__
are evaluated while the class is read and interpreted.
You can get about the same thing you want by simply define all the classes inside a module of their own. The importing the module, makes it an object whose fields are the classes you define in it.
I don’t think it’s good object oriented practice, but you can set inner class attributes at the outer class scope. For instance.
class Class2:
class Labels:
c2l1 = 'label 1'
c2l2 = 'label 2'
class Params:
pass
# p1 = None
# p2 = None
# p3 = None
Params.p1 = Labels.c2l2
Params.p2 = 1234
print(Class2.Params.p1)
print(Class2.Params.p2)
# print(Class2.Params.p3)
label 2
1234
These are all class attributes, but instance attributes should work similarly.
Another solution here is to turn Foo into a module and dedent the code.
Or One can do this by defining the Params class by using the type function.
This uses the Foo local scope.
class Foo(object):
class A(object):
pass
B = type('B', (object,), {'other': A})
print(Foo.A)
print(Foo.B)
print(Foo.B.other)
Prints out:
<class '__main__.Foo.A'>
<class '__main__.B'>
<class '__main__.Foo.A'>
I am trying to reference an inner class from another inner class. I have tried both :
class Foo(object):
class A(object):
pass
class B(object):
other = A
and
class Foo(object):
class A(object):
pass
class B(object):
other = Foo.A
with respective results:
Traceback (most recent call last):
File "python", line 1, in <module>
File "python", line 6, in Foo
File "python", line 7, in B
NameError: name 'A' is not defined
and
Traceback (most recent call last):
File "python", line 1, in <module>
File "python", line 6, in Foo
File "python", line 7, in B
NameError: name 'Foo' is not defined
Is this possible?
This is not possible, since everything you define in a class becomes a valid member only in an instance of that class, unless you define a method with @staticmethod
, but there is no such property for a class.
So, this won’t work either:
class Foo(object):
x = 10
class A(object):
pass
class B(object):
other = x
This will work, but it is not what you intended:
class Foo(object):
x = 10
class A(object):
pass
class B(object):
def __init__(self):
self.other = Foo.A
f = Foo()
print(f.B().other)
The output is:
<class '__main__.Foo.A'>
The reason this works is that the methods (in this case __init__
) are evaluated when the object is created, while assignment before the __init__
are evaluated while the class is read and interpreted.
You can get about the same thing you want by simply define all the classes inside a module of their own. The importing the module, makes it an object whose fields are the classes you define in it.
I don’t think it’s good object oriented practice, but you can set inner class attributes at the outer class scope. For instance.
class Class2:
class Labels:
c2l1 = 'label 1'
c2l2 = 'label 2'
class Params:
pass
# p1 = None
# p2 = None
# p3 = None
Params.p1 = Labels.c2l2
Params.p2 = 1234
print(Class2.Params.p1)
print(Class2.Params.p2)
# print(Class2.Params.p3)
label 2
1234
These are all class attributes, but instance attributes should work similarly.
Another solution here is to turn Foo into a module and dedent the code.
Or One can do this by defining the Params class by using the type function.
This uses the Foo local scope.
class Foo(object):
class A(object):
pass
B = type('B', (object,), {'other': A})
print(Foo.A)
print(Foo.B)
print(Foo.B.other)
Prints out:
<class '__main__.Foo.A'>
<class '__main__.B'>
<class '__main__.Foo.A'>