Reputation: 159
This does not work:
class A:
a1 = 4
class B:
b1 = A.a1 # Fails
b2 = 6
class C:
c1 = A.B.b2 # Fails
Any non cryptic way to solve it? I know I could take B and C out from A but I would like to keep them embedded. I also think it would be easier with no class members as they could easily passed to nested class as argument in constructor, but being all of them class members I do not know how to do some similar thing here. I have also read on some thread that this usage remembers using classes as namespaces and that should be solved using modules, not classes, but above classes are real classes for me (I construct instances) with class data in adition that I would like to share among them.
Upvotes: 9
Views: 2836
Reputation: 15388
One trick is to put the common parameters into a parameter class and inherit from that:
class Params:
p = 4
class A(Params):
# A has p
class B(Params):
# B has p
pass
class C(Params):
# C has p
pass
Or, if you need the params with different names in the inner classes:
class A(Params):
# A has p
class B:
b = Params.p
class C:
c = Params.p
This avoids having to monkey-patch the class after creation.
Upvotes: 1
Reputation: 168616
You might defer the definition of B
until A
is fully defined, and defer C
until both A
and A.B
are defined.
class A:
a1 = 4
class B:
b1 = A.a1
b2 = 6
A.B = B
del B
class C:
c1 = A.B.b2
A.C = C
del C
assert A.B.b1 == 4
assert A.C.c1 == 6
Alternatively, you could define B.b1
outside of B
's definition:
class A:
a1 = 4
class B:
pass
B.b1 = a1
B.b2 = 6
class C:
pass
C.c1 = B.b2
assert A.B.b1 == 4
assert A.C.c1 == 6
Upvotes: 3
Reputation: 76608
This fails for two different reasons. One is that A
is not ready when you try to access A.a1
in B
giving you NameError
.
If you solve this using a subclass. The following will work:
class A:
a1 = 4
class _A(A):
class B:
b1 = A.a1 # Fails
b2 = 6
However accessing A.B.b2
in C
will still not work as A
has no attribute B
. You will get an AttributeError
on that.
Upvotes: 1