2

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

Category.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

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

4

4 回答 4

2

您不能对属性执行此操作;您要么必须使用 a classmethod,要么为此创建自己的描述符

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'
于 2013-01-15T14:29:29.563 回答
2

您可能想使用类方法:

class Category(object):

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

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

于 2013-01-15T14:15:54.190 回答
1

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

class Category(object):
    # stuff...

现在您将两个全局对象放入其中:

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

你可以这样使用它:

from path.to.category import GOOD, BAD

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

于 2013-01-15T14:14:30.763 回答
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
于 2013-01-15T14:21:20.803 回答