class 作为同一 class 的 class 成员的实例
Instance of class as class member of the same class
创建 class 成员(它是 class 的实例)的最 "pythonic" 方法是什么? IE。像这样:
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!")
可以通过在 class 定义后添加一个成员来解决这个问题:
class MyClass:
...
MyClass.instance_as_member = MyClass()
但这似乎有点不对;自然地,class 成员应该被定义为 in 即 class.
有更好的方法吗?
那不是 "A little wrong" - 这是做到这一点的简单明了的方法。
一行代码,人人可读,一目了然"what it is"。
还是不"feel"优雅。
所以,如果你不想仅仅为了外观而这样做,也许,如果有很多像这样的 classes,而不是重复代码,它可以用 class 装饰器来完成:
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 作为参数进行修改。使用 metaclasses,这会很棘手,因为 class 实例化的某些步骤,例如调用 __init_subclass__
是在 任何显式 meta[=26 之后执行的=] 方法可以被覆盖,因此,尝试在 metaclass 初始化方法(__init__
、__new__
或 meta-meta-class' __call__
)
您似乎需要 setUp
类型的功能。这是在 class 中执行此操作的 "slightly dirty" 方法:设置一个 class 变量标志来表示首次使用 class。检查实例化标志;如果这是第一次访问,则清除标志和运行设置方法。
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)
虽然 class 未在正文中定义,但 是 在 __init__
中定义的
但是在__init__
里面实例化class有一个问题是递归的,所以需要跟踪instance_as_member
是否已经实例化
类似以下的作品:
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>
(至于这是否是个好主意是完全不同的问题!)
创建 class 成员(它是 class 的实例)的最 "pythonic" 方法是什么? IE。像这样:
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!")
可以通过在 class 定义后添加一个成员来解决这个问题:
class MyClass:
...
MyClass.instance_as_member = MyClass()
但这似乎有点不对;自然地,class 成员应该被定义为 in 即 class.
有更好的方法吗?
那不是 "A little wrong" - 这是做到这一点的简单明了的方法。 一行代码,人人可读,一目了然"what it is"。
还是不"feel"优雅。 所以,如果你不想仅仅为了外观而这样做,也许,如果有很多像这样的 classes,而不是重复代码,它可以用 class 装饰器来完成:
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 作为参数进行修改。使用 metaclasses,这会很棘手,因为 class 实例化的某些步骤,例如调用 __init_subclass__
是在 任何显式 meta[=26 之后执行的=] 方法可以被覆盖,因此,尝试在 metaclass 初始化方法(__init__
、__new__
或 meta-meta-class' __call__
)
您似乎需要 setUp
类型的功能。这是在 class 中执行此操作的 "slightly dirty" 方法:设置一个 class 变量标志来表示首次使用 class。检查实例化标志;如果这是第一次访问,则清除标志和运行设置方法。
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)
虽然 class 未在正文中定义,但 是 在 __init__
但是在__init__
里面实例化class有一个问题是递归的,所以需要跟踪instance_as_member
是否已经实例化
类似以下的作品:
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>
(至于这是否是个好主意是完全不同的问题!)