【问题标题】:how to define a class variable referring to an object of same class in python [duplicate]如何在python中定义引用同一类对象的类变量[重复]
【发布时间】:2013-06-07 13:30:00
【问题描述】:

下面是java代码。我需要知道python中的等效代码:

class A {
    public static A obj = new A();
}

【问题讨论】:

  • @PravatPanda -- 可能是因为 OP 试图在 python 中重现该 java 构造。想必最懂这个问题的人也懂java...
  • @mgilson 抱歉,我一开始没有理解这个问题。

标签: java python class static


【解决方案1】:

您不能在 python 类定义中执行此操作,因为直到 class: 块结束时才定义该类。您必须在以下时间设置它:

class A(object): 
    pass    
A.obj = A()

【讨论】:

  • 请注意,您通常不会在 Python 中执行此操作。在 Java 中这样做的原因是您导入类,而不是文件,因此将类的“默认”实例保留为该类本身的静态成员是有意义的。在 Python 中,您可以导入模块,并且实例可以存在于类之外,因此将类的默认实例设为定义该类的模块的模块级变量是有意义的。
【解决方案2】:

您可以使用元类来做到这一点:

class SelfReferencingObjectMetaclass(type):

    def __new__(cls, name, bases, attrs):

        attrs['obj'] = property(lambda self: self.__class__.obj)
        return super(SelfReferencingObjectMetaclass, cls).__new__(cls, name, bases, attrs)

    @property
    def obj(cls):

        try:
            return cls._obj
        except AttributeError:
            cls._obj = cls()
            return cls._obj

class A(object):

    __metaclass__ = SelfReferencingObjectMetaclass

正如@Daniel Roseman 在 cmets 中对@jamylak 的回答所指出的那样,可能有一种更简单、更 Pythonic 的方式来解决您遇到的问题。根据该评论,如果在对象结构方面不同,您将如何在功能上完成此操作,将是通过具有这样的模块:

a.py

class A(object):

    @property
    def obj(self):

        return a_inst


a_inst = A()

这确实在使用它的代码中创建了有点丑陋的构造 from a import A,但它是一种不太复杂的实现方式。

【讨论】:

  • 我其实也想过发布这个——主要是因为我刚刚开始学习元类,就像“嘿,我可以用元类解决这个问题!”
  • 元类对于某些事情来说是一个非常棒的工具。不过,过度使用它们有点危险。在这种情况下,我比cls.obj = cls()property 在我的答案中更喜欢它们,只是因为我真的讨厌from a import A 构造的冗余。虽然更常见的是,您可以通过调整实现并将类提升到层次结构的一级或二级来避免这两个问题。
  • 我认为@DanielRoseman 意味着您的第二个代码将是模块a 中的class A(object): passobj 将是a.obj 否则我看不到@property 对我的任何优势代码
  • 没有一个,真的,只是一个替代方案,可以说在非玩具示例中更有用。此外,可以说它更“安全”和类似静态,这在这种情况下可以被视为一个优势,因为a_inst 可以被视为类的实现细节,而A.obj 是不可分配的。当然,它确实有一个缺点,就是无法从类中访问它,但是您可以使用描述符来解决这个问题,当然也可以使用元类。
【解决方案3】:

在创建类的任何实例之前您是否需要该类成员?如果不是,您可以尝试在创建第一个实例时分配它:

class A (object):
    obj = None

    def __init__(self):
        if A.obj is None:
            a.obj = A()
            # or:
            a.obj = self

【讨论】:

  • 或者早点做,__new__
【解决方案4】:

我认为您愿意这样做是因为您正在尝试实现单例或类似的模式。

您可以从 activestate 中阅读以下配方:http://code.activestate.com/recipes/52558/

它解释了它的工作方式并显示了一些代码。

【讨论】:

    猜你喜欢
    • 2022-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 2018-04-23
    • 1970-01-01
    • 2015-02-05
    相关资源
    最近更新 更多