Instance of class as class member of the same class
创建类成员(该类的实例)的最"Python式"方法是什么?也就是这样:
1 2 3 4 5 6 7 | class MyClass: # error! (and this is to be expected as MyClass is not yet fully defined) instance_as_member = MyClass() def __init__(self): print("MyClass instance created!") |
可以通过在类定义之后添加成员来解决此问题:
1 2 3 | class MyClass: ... MyClass.instance_as_member = MyClass() |
但这似乎有点错误;当然,应该在该类中定义类成员。
有更好的方法吗?
这不是"有点错"——这是一种简单而明显的方法。一行代码,每个人都可以阅读,并且很明显"它是什么"。
但它仍然不"感觉"优雅。因此,如果您不想仅仅为了外观而这样做,并且可能,如果有许多这样的类,不重复代码,那么可以使用类修饰器来完成:
1 2 3 4 5 6 7 8 9 10 | def instance_as_member(attr_name='instance_as_member', *init_args, **init_kwargs): def decorator(cls): instance = cls(*init_args, **init_kwargs) setattr(cls, attr_name, instance) return cls return decorator @instance_as_member() class MyClass: ... |
装饰师可以这样做,因为他们让CLS在完全创建后被修改为参数。对于元类来说,这是很困难的,因为类实例化的某些步骤,如调用
虽然类没有在主体中定义,但它是在
但是,存在一个问题,即在
类似于以下作品:
1 2 3 4 5 6 7 8 9 10 11 12 | class Foo: member_added = False instance_as_member = None def __init__(self): if not Foo.member_added: Foo.member_added = True Foo.instance_as_member = Foo() print(Foo.instance_as_member) Foo() print(Foo.instance_as_member) |
这将导致:
None
<__main__.Foo object at 0x7fcd9f68f3c8>
(至于这是不是一个好主意是一个完全不同的问题!)
您似乎需要
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class MyClass: first_touch = True def __init__(self, id=0): if MyClass.first_touch: MyClass.setUp(id) print("MyClass instance created!", id) @classmethod def setUp(self, id): MyClass.first_touch = False MyClass.instance_as_member = MyClass(-999) print("Start") local_obj = MyClass(1) local_obj = MyClass(2) local_obj = MyClass(3) |