我有一个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方法来创建这样的类别对象。
答案 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