Python - ссылочный внутренний класс из другого внутреннего класса
Я пытаюсь ссылаться на внутренний класс из другого внутреннего класса. Я пробовал оба:
class Foo(object):
class A(object):
pass
class B(object):
other = A
а также
class Foo(object):
class A(object):
pass
class B(object):
other = Foo.A
с соответствующими результатами:
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
а также
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
Это возможно?
3 ответа
Это невозможно, поскольку все, что вы определяете в классе, становится действительным членом только в экземпляре этого класса, если только вы не определили метод с @staticmethod
, но нет такого свойства для класса.
Так что это тоже не сработает:
class Foo(object):
x = 10
class A(object):
pass
class B(object):
other = x
Это будет работать, но это не то, что вы хотели:
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)
Выход:
<class '__main__.Foo.A'>
Причина, по которой это работает, заключается в том, что методы (в данном случае __init__
) оцениваются при создании объекта, в то время как __init__
оцениваются, пока класс читается и интерпретируется.
Вы можете получить примерно то же, что и вы, просто определив все классы внутри собственного модуля. Импортируя модуль, он становится объектом, поля которого являются классами, которые вы в нем определяете.
Я не думаю, что это хорошая объектно-ориентированная практика, но вы можете установить атрибуты внутреннего класса в области внешнего класса. Например.
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
Это все атрибуты класса, но атрибуты экземпляра должны работать аналогично.
Другим решением здесь является превращение Foo в модуль и уменьшение кода.
Или можно сделать это, определив класс B с помощью функции типа. Это использует локальную область видимости Foo.
class Foo(object):
class A(object):
pass
B = type('B', (object,), {'other': A})
print(Foo.A)
print(Foo.B)
print(Foo.B.other)
Распечатывает:
<class '__main__.Foo.A'>
<class '__main__.B'>
<class '__main__.Foo.A'>