如何在Python中实现类似Java的枚举?
这段话是在问,怎么用Python来表达这段Java代码。
public static enum Operations {Add, Subtract, Multiply, Divide, None};
我正在把一个完整的程序转换成Python,但我就是搞不懂这一部分。
这是我的整个类的代码。
import java.util.*;
public class Expression
{
public static enum Operations {Add, Subtract, Multiply, Divide, None};
int a;
int b;
Expression.Operations op;
public Expression()
{
a = 0;
b = 0;
op = Expression.Operations.None;
}
public Expression(int value1, int value2, Expression.Operations operation)
{
a = value1;
b = value2;
op = operation;
}
public boolean parseString(String expressionString, Map<Character, Integer> vars)
{
Scanner scanner = new Scanner(expressionString);
//Attempt to read the first value.
if (scanner.hasNextInt())
a = scanner.nextInt();
else if (scanner.hasNext())
{
String var = scanner.next();
//Ensure that the variable identifier is a single alphabetical character in length.
if (!var.matches("[A-Z]{1}"))
{
return false;
}
if (vars.containsKey(var.charAt(0)))
a = vars.get(var.charAt(0));
else
{
System.err.println("ERROR: Uninitialized variable.");
return false;
}
}
else return false;
//If more tokens exist, attempt to read the operator.
if (scanner.hasNext())
{
String operator = scanner.next();
if (operator.equals("+"))
op = Expression.Operations.Add;
else if (operator.equals("-"))
op = Expression.Operations.Subtract;
else if (operator.equals("*"))
op = Expression.Operations.Multiply;
else if (operator.equals("/"))
op = Expression.Operations.Divide;
else
return false;
//Attempt to read the second value.
if (scanner.hasNextInt())
b = scanner.nextInt();
else if (scanner.hasNext())
{
String var = scanner.next();
//Ensure that the variable identifier is a single alphabetical character in length.
if (!var.matches("[A-Z]{1}"))
{
return false;
}
b = vars.get(var.charAt(0));
}
else return false;
}
return true;
}
public int evaluate()
{
int value = 0;
if (op == Expression.Operations.Add)
value = a + b;
if (op == Expression.Operations.Subtract)
value = a - b;
if (op == Expression.Operations.Multiply)
value = a * b;
if (op == Expression.Operations.Divide)
value = a / b;
if (op == Expression.Operations.None)
value = a;
return value;
}
}
8 个回答
7
你可以随时使用一个命名元组(NamedTuple)
>>> import collections
>>> Enum = collections.namedtuple('Enum','Add Subtract Multiply Divide None_')
>>> Enum(*range(1,6))
Enum(Add=1, Subtract=2, Multiply=3, Divide=4, None_=5)
>>> operations = _
>>> operations.Add
1
在较新的Python版本中,你不能把值赋给None
,所以我把它改成了None_
。
9
Python没有专门的枚举类,它只是用普通的整数来实现这个功能。要把一个模板部分放到类里,最简单的方法是这样做:
class Operation:
ADD, SUBTRACT, MULTIPLY, DIVIDE, NONE = range(5)
这样做会把add赋值为0,把none赋值为4。这是最简单明了的做法(而且可以确保在这个序列中没有两个枚举值是相同的数字,也能保证你没有漏掉给某个数字赋值)。
5
在Python中,任何属性或方法默认都是公开的,除非你在名字前面加下划线。这里是Python 2.7教程中相关的部分。
Python没有完全复制static
功能的方法,但你在类中定义的任何属性都会像static
变量一样在实例中可见。只需在类定义中写attribute = value
就可以了。
在Python中,你不能让值变成constant
(常量),但通常的做法是用UPPERCASE_IDENTIFIERS
(全大写的标识符)来表示你想要常量的意思。
Python没有枚举(Enums)的概念。通常会用普通的字符串常量来代替这个功能。你只需将"add"
、"subtract"
、"multiply"
、"divide"
或None
传递给你的函数。
例如,在你的解析器中
if (operator.equals("+"))
op = Expression.Operations.Add;
会变成
if operator == "+":
op = "add"
而在你的评估器中
if (op == Expression.Operations.Add)
value = a + b;
会变成
if op == "add"
value = a + b