从python中的静态属性创建对象

时间:2013-01-15 14:08:59

标签: python properties static object-construction

我有一个Category类,每个类别都有不同的名称,类别的名称可能是未知的,好的和坏的,所有类别共享相同的行为,所以我不想为每种类别创建子类,当我想要的时候问题来了 以这种方式创建不同的类别:

Category.GOOD

此语句应返回一个类别对象,其名称设置为“good”,所以我尝试 以下内容:

class Category(object):                                                                                                            

  def __init__(self, name):                                                                                                      
      self.name = name                                                                                                           

  @property
  def GOOD(self):
      category = Category(name='good')                                                                                           
      return category                                                                                                            

  @property
  def BAD(self): 
      category = Category(name='bad')                                                                                            
      return category   

然后我创建并使用具有以下输出的类别:

c = Category.GOOD
c.name
AttributeError: 'property' object has no attribute 'name'

意识到这不起作用我尝试类似java的方法:

class Category(object):                                                                                                          

    GOOD = Category(name='good')
    BAD = Category(name='bad')                                                                                                   

    def __init__(self, name):
        self.name = name

我得到的是一个未定义的名称“类别”错误,所以我的问题是是否有一种pythonic方法来创建这样的类别对象。

4 个答案:

答案 0 :(得分:2)

您可能想要使用classmethods:

class Category(object):

    @classmethod
    def GOOD(cls):
        category = cls(name='GOOD')
        return category

现在你可以c = Category.GOOD()

答案 1 :(得分:2)

你不能用财产做这件事;您必须使用classmethod,或为此创建自己的descriptor

class classproperty(property):
    def __get__(self, inst, cls):
        return self.fget(cls)

我在这里滥用property装饰者;它也实现了__set____del__,但为方便起见,我们可以忽略这些。

然后使用它代替property

class Category(object):
    def __init__(self, name):
        self.name = name

    @classproperty
    def GOOD(cls):
        return cls(name='good')

    @classproperty
    def BAD(cls):
        return cls(name='bad')

现在访问Category.GOOD有效:

>>> Category.GOOD
<__main__.Category object at 0x10f49df50>
>>> Category.GOOD.name
'good'

答案 2 :(得分:1)

我会为此使用模块变量。考虑您有模块category.py

class Category(object):
    # stuff...

现在你把两个全局对象放在其中:

GOOD = Category(name='good')
BAD = Category(name='bad')

你可以这样使用它:

from path.to.category import GOOD, BAD

我不是说这是 pythonic 但我认为这种方法很优雅。

答案 3 :(得分:0)

您不能在该类定义本身内使用类定义的要点。因此,实现您想要的最直接的方法是使用如下所示的类/静态方法,甚至是包常量。

class Category(object):
    def __init__(self, name):
        self.name = name

    @classmethod
    def GOOD(cls):
        return Category(name='good')

    @classmethod
    def BAD(cls):
        return Category(name='bad')

print Category.GOOD().name

class Category(object):
    def __init__(self, name):
        self.name = name

    @staticmethod
    def GOOD():
        return Category(name='good')

    @staticmethod
    def BAD():
        return Category(name='bad')

print Category.GOOD().name