什么是Pythonic初始化属性或属性的方法?

时间:2012-02-08 21:26:14

标签: python object coding-style

Python支持类属性,实例属性和属性。

from time import ctime, sleep

class MyClass(object):
    A = ctime()            # class attribute
    def __init__(self):
        self.B = ctime()   # instance attribute
        self._C = None

    @property
    def C(self):           # property
        if self._C is None:
            self._C = ctime()
        return self._C
    @C.setter
    def C(self, c):
        self._C

对于不知道如何实现MyClass的用户,A,B和C显示类似的行为:

sleep(2)
myObject = MyClass()
sleep(2)
print myObject.A         # prints time module was initialized
print myObject.B         # prints time instance was created, 2 sec later
print myObject.C         # prints time this line was called, 2 sec later
myObject.A = 'foo'       # myObject.A is now an instance attribute
myObject.B = 'foo'       # myObject.B is still an instance attribute
myObject.C = 'foo'       # myObject.C is still an (instance) property
print myObject.A         # prints 'foo'
print myObject.B         # prints 'foo'
print myObject.C         # prints 'foo'

根据我到达的答案,我了解以下内容:第一次打印myObject.A时,myObject.A myObject.__Class__.AMyClass.AmyObject.A。第二次myObject.__Class__.A不是ctime()。细

在上面的示例中,class MyClass(object): A = 'bar' # class attribute def __init__(self): self.B = 'meta' # instance attribute self._C = None @property def C(self): # property if self._C is None: self._C = 'foobar' return self._C @C.setter def C(self, c): self._C = c myObject = MyClass() 仅用于说明A,B和C的不同之处。现在假设,我们使用的是不可变常量:

myObject.A

MyClass.A仍然是类属性myObject.B,而myObject.C是实例属性,{{1}}是属性。所有这些,完全符合我的要求。它们有一个默认值,我可以分配一些其他值。我应该使用哪种风格,A,B或C?

3 个答案:

答案 0 :(得分:1)

这取决于您希望初始化运行以及您想要的实例化。

  • 如果您希望在该类的所有实例之间共享该属性的单个实例(即单个值),请使用类属性。
  • 如果您希望类的每个实例都具有该属性的不同值,请使用实例属性。

另外,您的代码示例包含属性而不是属性。

我无法理解您对该问题的更新。您可能需要退后一步并解释您的潜在问题。

答案 1 :(得分:1)

  

似乎有两种创建简单属性或属性的方式。

它们根本不是“风格”,只有一件事要做:分配。

它们有不同的效果。

在Python中,遵循逻辑规则,class块中声明的内容属于该类。因此A是类的属性(大致类似于C ++或Java或C#中声明为static的属性)。 B是每个实例的属性,在实例上运行__init__时自动生成。

至于你的更新,我不知道你想要问什么。尝试使用真实姓名而不是“A”并解释您的使用案例(即为什么您想要做任何事情)。

答案 2 :(得分:0)

初始化常量类属性的首选方法是在类定义中。

查看问题中的代码,似乎对如何从实例对象访问类属性存在一些困惑。

请注意,在实例对象中,您可以按名称访问类属性,因为当在内部字典中找不到属性时,查找将继续在类字典中进行。也就是说,如果instance.A不存在,instance.__class__.A将会返回,如果它可用的话。

但是,在对象实例中创建属性时,class属性将被遮蔽。也就是说,instance.A = <value>会创建一个新的实例属性,下次您访问instance.A时,会返回<value>。但是,仍然可以使用instance.__class__.A检索class属性。