类实例作为同一类的类成员

时间:2019-01-04 19:32:10

标签: python python-3.x class-members

创建作为该类实例的类成员的最“ pythonic”方法是什么?即像这样的东西:

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 MyClass:
    ...
MyClass.instance_as_member = MyClass()

但这似乎有点错误;自然,应该在该类的 中定义该类的成员。

有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

这不是“有点不对劲”-这是简单明了的方法。 一行代码,每个人都可以读取,并且显而易见是“它是什么”。

它仍然没有“感觉”优雅。 因此,如果您不想只是为了外观而这样做,并且也许,如果有很多这样的类而不重复代码,则可以使用类装饰器来完成:

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修改为参数。对于元类,这将很棘手,因为类实例化的某些步骤(如调用__init_subclass__会在所有可以被覆盖的显式元类方法之后之后执行,因此,尝试创建一个元类方法可能会遇到问题。元类初始化方法({{1},__init__或元元类的__new__)中的实例

答案 1 :(得分:0)

您似乎需要setUp类型的功能。这是在类内执行此操作的一种“稍脏”方法:设置类变量标志以表示该类的首次使用。检查实例化标志;如果这是第一次访问,请清除该标志并运行设置方法。

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)

答案 2 :(得分:0)

虽然该类未在主体内定义,但在__init__

内定义了

但是,存在一个问题,即在__init__中实例化该类是递归的,因此您需要跟踪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)

结果是:

  

没有
  <__ main__.Foo对象位于0x7fcd9f68f3c8>

关于这是否一个好主意是完全不同的问题!