带元类的Python类枚举构造
出于某种原因,在一个星期天的早晨,我觉得我需要为我正在写作的科学图书馆做以下几件事:带元类的Python类枚举构造,python,python-3.x,Python,Python 3.x,出于某种原因,在一个星期天的早晨,我觉得我需要为我正在写作的科学图书馆做以下几件事: class PolarityType(type): """Metaclass to construct polarity types. Supports conversion to float and int.""" def __float__(cls): return int(cls) def __int__(cls): return cls.P
class PolarityType(type):
"""Metaclass to construct polarity types. Supports conversion to float and int."""
def __float__(cls):
return int(cls)
def __int__(cls):
return cls.P
class Polarity(metaclass=PolarityType):
"""Base class to build polarity."""
P = 0
class PositivePolarity(Polarity):
"""Positive polarity."""
P = 1
class NegativePolarity(Polarity):
"""Negative polarity."""
P = -1
>>> float(NegativePolarity)
>>> -1.0
基本上,我没有传递参数,比如polarity='POSITIVE'
和检查字符串,也因为我使用类型提示,所以我希望它是强类型的,我编写了上面的代码
有没有更简单/更干净/更好的方法来达到同样的效果?这有意义吗?您的解决方案可行,但有没有特别的理由不使用
导入枚举
类极性(enum.enum):
正:浮动=1.0
负:浮点=-1.0
定义浮点数(cls):
回归自我价值
定义(cls):
返回int(self.value)
打印(极性.负极,类型(极性.负极))
#极性
打印(类型(极性.负.值),极性.负.值)
# -1.0
打印(类型(浮动(极性.负极)),浮动(极性.负极))
# -1.0
您的解决方案可行,但是否有特殊原因不使用
导入枚举
类极性(enum.enum):
正:浮动=1.0
负:浮点=-1.0
定义浮点数(cls):
回归自我价值
定义(cls):
返回int(self.value)
打印(极性.负极,类型(极性.负极))
#极性
打印(类型(极性.负.值),极性.负.值)
# -1.0
打印(类型(浮动(极性.负极)),浮动(极性.负极))
# -1.0
有什么原因不能直接使用常规INT进行此操作?也就是说,NegativePolarity=-1
使用类型系统感觉更健壮,另外,我可以输入提示。我看到人们在层次结构中更进一步,在Haskell中将类型视为值,但在Python中?它甚至没有一个合适的类型检查器。我不确定我是否理解其动机,但如果您想键入hint函数参数,比如说NegativePolarity
,这与根本不传递此参数有什么区别,因为您知道极性是负的?@Norrius回答您的第二个问题:我会键入hint作为PolarityType
,例如def foo(polarity:PolarityType=PositivePolarity):通过
。嗯,好吧,这看起来很合理(mypy也同意)。为了避免元类,您还可以定义类似于PositivePolarity=polarity(1)
,然后将其用作def(p:polarity=PositivePolarity):pass
,它与enums非常相似。有没有一个原因你不能只使用常规int来实现这一点?那就是,NegativePolarity=-1
使用类型系统感觉更健壮,另外,我可以键入提示。我见过人们在Haskell中将类型作为值来处理层次结构,但在Python中?它甚至没有正确的类型e checker.我不确定我是否理解其动机,但如果你想键入一个函数参数,比如说NegativePolarity
,那与根本不传递这个参数有什么区别,因为你知道极性是负的?@Norrius回答你的第二个问题:我会键入hint作为PolarityType
,例如de>f foo(polarity:PolarityType=PositivePolarity):pass
。嗯,好吧,看起来不错(mypy也同意)。为了避免元类,您还可以定义类似于PositivePolarity=polarity(1)
,然后将其用作定义f(p:polarity=PositivePolarity):pass
,它与enum非常相似。看起来很棒。我承认我从未使用过enum
并忘记了它。看起来很棒。我承认我从未使用过enum
并忘记了它。
import enum
class Polarity(enum.Enum):
POSITIVE: float = 1.0
NEGATIVE: float = -1.0
def __float__(cls):
return self.value
def __int__(cls):
return int(self.value)
print(Polarity.NEGATIVE, type(Polarity.NEGATIVE))
# Polarity.NEGATIVE <enum 'Polarity'>
print(type(Polarity.NEGATIVE.value), Polarity.NEGATIVE.value)
# <class 'float'> -1.0
print(type(float(Polarity.NEGATIVE)), float(Polarity.NEGATIVE))
# <class 'float'> -1.0