Python:将对象分组在一起
让我们看一段定义算术运算符对象(标记)的代码: 我希望操作符被分组到某个地方,这样我就可以迭代它们或检查成员资格。因为我以后会添加很多其他操作符,所以我希望只能在一个位置添加它们,而不是在两个位置添加它们(实现一个操作符,但忘记将其添加到Python:将对象分组在一起,python,object,dictionary,tuples,grouping,Python,Object,Dictionary,Tuples,Grouping,让我们看一段定义算术运算符对象(标记)的代码: 我希望操作符被分组到某个地方,这样我就可以迭代它们或检查成员资格。因为我以后会添加很多其他操作符,所以我希望只能在一个位置添加它们,而不是在两个位置添加它们(实现一个操作符,但忘记将其添加到操作符可能会导致微妙的错误)。我试过这样的方法 operators = (PLUS = Operator(0), MIN = Operator(0), ...) 和之类似,但这显然不是一个有效的Python语句 我目前使用的解决方案是dict定义: opera
操作符
可能会导致微妙的错误)。我试过这样的方法
operators = (PLUS = Operator(0), MIN = Operator(0), ...)
和之类似,但这显然不是一个有效的Python语句
我目前使用的解决方案是dict
定义:
operators = dict(
PLUS=Operator(0),
MIN=Operator(0),
...
)
这可以正常工作,但这意味着任何时候我想使用单个操作符,我必须将其称为例如
操作符['PLUS']
,而不是更短更清晰的PLUS
。我可以接受,但我想知道是否存在更好的问题解决方案。您可以执行以下操作:
class Operator:
def __init__(self, precedence):
self.precedence = precedence
Operator.PLUS = Operator(0)
Operator.UPLUS = Operator(10)
Operator.MIN = Operator(0)
Operator.UMIN = Operator(10)
Operator.MULT = Operator(20)
[o for o in dir(Operator) if not o.startswith('__')]
您可以执行以下操作:
class Operator:
def __init__(self, precedence):
self.precedence = precedence
Operator.PLUS = Operator(0)
Operator.UPLUS = Operator(10)
Operator.MIN = Operator(0)
Operator.UMIN = Operator(10)
Operator.MULT = Operator(20)
[o for o in dir(Operator) if not o.startswith('__')]
为什么不让操作员加入您的组
class Operator:
all = []
def __init__(self, precedence):
self.precedence = precedence
self.all.append(self) # Modifies the class variable, as we haven't
# introduced an instance variable with that name.
PLUS = Operator(0)
UPLUS = Operator(10)
MIN = Operator(0)
UMIN = Operator(10)
MULT = Operator(20)
# Freeze the collection of Operators
Operator.all = tuple(Operator.all)
当然,这也适用于模块级变量中的集合:
operators = []
class Operator:
def __init__(self, precedence):
self.precedence = precedence
operators.append(self)
PLUS = Operator(0)
UPLUS = Operator(10)
MIN = Operator(0)
UMIN = Operator(10)
MULT = Operator(20)
# Freeze the collection of Operators
operators = tuple(operators)
如果必须将运算符添加到多个组中的一个组,请将表示该组的集合设置为将运算符添加到用于初始化运算符的强制参数:
u_operators = []
non_u_operators = []
class Operator:
def __init__(self, precedence, group):
self.precedence = precedence
group.append(self)
PLUS = Operator(0, non_u_operators)
UPLUS = Operator(10, u_operators)
MIN = Operator(0, non_u_operators)
UMIN = Operator(10, u_operators)
MULT = Operator(20, non_u_operators)
# Freeze the collections of Operators
non_u_operators = tuple(non_u_operators)
u_operators = tuple(u_operators)
为什么不让操作员加入您的组
class Operator:
all = []
def __init__(self, precedence):
self.precedence = precedence
self.all.append(self) # Modifies the class variable, as we haven't
# introduced an instance variable with that name.
PLUS = Operator(0)
UPLUS = Operator(10)
MIN = Operator(0)
UMIN = Operator(10)
MULT = Operator(20)
# Freeze the collection of Operators
Operator.all = tuple(Operator.all)
当然,这也适用于模块级变量中的集合:
operators = []
class Operator:
def __init__(self, precedence):
self.precedence = precedence
operators.append(self)
PLUS = Operator(0)
UPLUS = Operator(10)
MIN = Operator(0)
UMIN = Operator(10)
MULT = Operator(20)
# Freeze the collection of Operators
operators = tuple(operators)
如果必须将运算符添加到多个组中的一个组,请将表示该组的集合设置为将运算符添加到用于初始化运算符的强制参数:
u_operators = []
non_u_operators = []
class Operator:
def __init__(self, precedence, group):
self.precedence = precedence
group.append(self)
PLUS = Operator(0, non_u_operators)
UPLUS = Operator(10, u_operators)
MIN = Operator(0, non_u_operators)
UMIN = Operator(10, u_operators)
MULT = Operator(20, non_u_operators)
# Freeze the collections of Operators
non_u_operators = tuple(non_u_operators)
u_operators = tuple(u_operators)
您可以使用
枚举
:
from enum import Enum
class Operator:
def __init__(self, precedence):
self.precedence = precedence
def __str__(self):
return "Operator: prec={}".format(self.precedence)
class Operators(Enum):
PLUS = Operator(0)
UPLUS = Operator(10)
MIN = Operator(0)
UMIN = Operator(10)
MULT = Operator(20)
p = Operators.PLUS
print(p) # Operators.PLUS
print(p.name) # PLUS
print(p.value) # Operator: prec=0
您可以使用
枚举
:
from enum import Enum
class Operator:
def __init__(self, precedence):
self.precedence = precedence
def __str__(self):
return "Operator: prec={}".format(self.precedence)
class Operators(Enum):
PLUS = Operator(0)
UPLUS = Operator(10)
MIN = Operator(0)
UMIN = Operator(10)
MULT = Operator(20)
p = Operators.PLUS
print(p) # Operators.PLUS
print(p.name) # PLUS
print(p.value) # Operator: prec=0
我决定这样做(我也喜欢Enum解决方案,但引用元素有点冗长-例如
操作符.PLUS.value
)。但是我遇到了一个问题,我将把它编辑到OP中。没关系,我在代码中发现了这个问题。这个解决方案很好,我只是在\uuuu init\uuuu
中包含了一个检查if group
,并且忘记了空列表在bool表达式中也计算为False
。如果组不是None,则更改为,现在可以正常工作。干杯我决定这样做(我也喜欢Enum解决方案,但引用元素有点冗长-例如操作符.PLUS.value
)。但是我遇到了一个问题,我将把它编辑到OP中。没关系,我在代码中发现了这个问题。这个解决方案很好,我只是在\uuuu init\uuuu
中包含了一个检查if group
,并且忘记了空列表在bool表达式中也计算为False
。如果组不是None,则更改为,现在可以正常工作。干杯+1表示枚举。还值得一提的是,枚举可以被枚举([op for op in Operators]
),并且具有快速成员身份检查(Operators.PLUS in Operators
)+1的枚举。还值得一提的是,枚举可以枚举([op for op in Operators]
)并具有快速成员身份检查(Operators.PLUS in Operators
)