【发布时间】:2018-10-29 08:03:31
【问题描述】:
考虑下面的代码:
class A(object):
attr = None
def __init__(self):
assert A.attr is not None
class B(object):
def __init__(self, attr):
A.attr = attr
class C(A):
def __init__(self):
super().__init__()
class D(A):
def __init__(self):
super().__init__()
nested_classes = {cls.__name__: cls for cls in {C, D}}
上面似乎没有按我的预期工作,因为:
>>> first_class = B("first")
>>> first_sub_class = first_class.C()
>>> first_sub_class.attr
'first'
>>> second_class = B("second")
>>> second_sub_class = second_class.C()
>>> second_sub_class.attr
'second'
>>> first_sub_class.attr
'second'
有没有办法让first_sub_class.attr 成为first 而让second_sub_class.attr 成为second?可能是因为有一个范围在 B 内的元类?
几点:
- 我不想传递
attr,我想在 B 初始化时设置它。 - 我不想通过使用
partial来绕过上面的点,因为它会破坏依赖__name__或__qualname__或类似的代码的其余部分。 - 我想尽可能忠实于当前的结构。
【问题讨论】:
-
这些类都不是元类。
-
没有pythonic方式。只是传递它。
-
@Aran-Fey 从某种意义上说,它们都不是元类,它们不使用
__metaclass__。很明显C(A)如果没有设置attr就不能创建。无论您是否使用__metaclass__编写它都不会对我的目的产生影响,如果它让您满意,我可以重写示例。我想看看我是否可以让 A 没有像现在一样被动态限定范围! -
@MegaIng 不在乎什么是 Pythonic。只要我不必进行字符串插值和
exec,我就可以有一个解决方案。 -
我不知道您打算将此代码用于什么目的,但我确实知道不应该这样做。从在另一个类的构造函数中设置类属性到通过实例访问该类属性,这段代码的一切都有味道。我建议您退后一步,询问您的实际 问题,而不是询问如何修复此代码。不会有任何好处。
标签: python metaprogramming metaclass