2016-03-27 72 views
1

让我们以下面的一段代码,定义算术运算符对象(标记):的Python:组合对象在一起

class Operator: 
    def __init__(self, precedence): 
     self.precedence = precedence 

PLUS = Operator(0) 
UPLUS = Operator(10) 
MIN = Operator(0) 
UMIN = Operator(10) 
MULT = Operator(20) 
operators = PLUS, UPLUS, MIN, UMIN, MULT 

我想运营商在某处被分组,这样我可以在他们重复或检查的成员。因为我稍后会添加很多其他人,所以我想只能将它们添加到一个地方,而不是两个(实现一个操作员,但忘记将其添加到operators可能导致微妙的错误)。我试过类似

operators = (PLUS = Operator(0), MIN = Operator(0), ...) 

和类似的,但这显然不是一个有效的Python语句。

我目前使用的解决方案是一个dict定义:

operators = dict(
    PLUS=Operator(0), 
    MIN=Operator(0), 
    ... 
) 

该工程确定,但它意味着任何时候我想用一个单一运营商的工作,我必须把它称为例如operators['PLUS'],而不是更简短更清晰的​​。我可以住在哪里,但我想知道是否存在更好的解决方案。

回答

1

为什么不能有运营商自己添加到您的组?

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) 
+0

我决定这样做(我也喜欢Enum解决方案,但引用元素有点冗长 - 例如, 'Operators.PLUS.value')。但是我遇到了一个问题,我将编辑到OP中。 –

+0

没关系,我在我的代码中发现了问题。这个解决方案没问题,我只是在'__init__'中包含了一个检查'if group',并忘记了空列表在bool表达式中也被评估为'False'。更改为“如果组不是无”,现在工作正常。干杯! –

1

你可以这样做:

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('__')] 
2

你可以使用一个Enum

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 
+1

对于枚举+1。值得一提的是,枚举可以枚举('[op for Operators]')并且具有快速的成员检查('Operators.PLUS in Operators') – Quantum7