如何在Python中实现类似Java的枚举?

时间:2011-07-26 03:37:47

标签: java python enums

说这个的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 个答案:

答案 0 :(得分: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_

答案 1 :(得分:6)

Python没有枚举类。它只是使用正常的整数。使模板成为类的一部分的最简单方法是执行以下操作:

class Operation:
    ADD, SUBTRACT, MULTIPLY, DIVIDE, NONE = range(5)

将分配添加到0而不分配给4.这是最干净的方式(并且它将保证您在此序列中没有任何具有相同数字但您没有的枚举错过了给其中一个号码分配内容。

答案 2 :(得分:5)

在Python中,任何属性或方法都被视为公共属性或方法,除非您在其名称的开头加上下划线。 Here is the relevant section in the Python 2.7 tutorial

Python没有完全复制static函数的方法,但是您在类中定义的任何属性都将在实例中以与static变量相同的方式显示。只需attribute = value在您的课程定义中,您就可以了。

你不能在Python中创建值constant,但惯例是使用UPPERCASE_IDENTIFIERS来表示意图。

枚举不存在。在Python中,普通字符串常量通常用于此目的。只需将"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

答案 3 :(得分:3)

dict可以提供符号和函数之间的映射。 operator模块可以方便地访问表达式中使用的内置函数。此外,通过使其成为只读属性,您可以保护某些属性不会被错误代码意外修改。尝试修改它们会在运行时引发AttributeError。如果有人真的需要写访问权限,它仍然可以通过下划线前缀变量获得,但这是一个私有接口。

import operator

class Expression(object):

    _OP_MAP = dict((x, getattr(operator, y)) for x, y in 
        [('*', 'mul'), ('/', 'truediv'), ('//', 'floordiv'), 
         ('+', 'add'), ('-', 'sub')])

    _OP_MAP[None] = lambda a, b: a

    a = property(lambda self: self._a)   #read-only interface
    b = property(lambda self: self._b) 
    op = property(lambda self: self._op)

    def __init__(self, value1=0, value2=0, operation=None):
        self._a = value1                 #mutable -- we're all adults
        self._b = value2
        self._op = self._OP_MAP[operation]

    def parse_string(self, expression_string, variables): 
        #...
        self._op = self._OP_MAP.get(operator) #defaults to None

    def evaluate(self):
        return self.op(self.a, self.b)

    def __repr__(self): 
        for k, v in self._OP_MAP.items():
            if self.op == v:
                return '{0} {1} {2}'.format(self.a, k, self.b)

答案 4 :(得分:2)

最好的方法就是:

class Operations:
    Add=1
    Subtract=2
    Multiply=3
    Divide=4
    None=5

答案 5 :(得分:0)

java中的枚举依赖于http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern - java中的枚举如:Enum&gt;。所以,除非python支持那种东西,否则你可能需要使用类似的东西 Typesafe枚举模式:http://java.sun.com/developer/Books/effectivejava/Chapter5.pdf

答案 6 :(得分:0)

我喜欢枚举,我希望Python有某种官方枚举。

这是我写的关于Python枚举的另一个答案的链接:

How can I represent an 'Enum' in Python?

这里是我推荐的配方的直接链接:

http://code.activestate.com/recipes/413486/

答案 7 :(得分:0)

Python最新版本确实支持枚举,只是想在阅读完以上所有响应后关闭循环

https://docs.python.org/3/library/enum.html