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

3

这句话在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;
    }
}

2
Duplicatehttps://dev59.com/FHVD5IYBdhLWcg3wQZUg - user747858
我添加了整个类,这样你就可以看到我想做什么。 - Misty
8个回答

9

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

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

这将把add赋值为0,none赋值为4。这是最清晰的做法(它可以保证在此序列中没有枚举号码相同且没有漏掉给其中一个编号分配某些内容)。


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_

5
在Python中,除非你在其名称开头加下划线,否则任何属性或方法都被视为公共的。这是Python 2.7教程中相关章节
Python没有一种确切地复制“static”函数的方式,但是您定义在类上的任何属性将以与静态变量相同的方式在实例中可见。只需在类定义中使用“attribute = value”,您就可以了。
在Python中,您无法使值为“constant”,但惯例是使用大写标识符来表示此意图。
枚举不存在。在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

字典可以提供符号与函数之间的映射关系。 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)

这个覆盖了类中的所有内容吗? - Misty
你觉得你想被雇用吗?哈哈...只有三个课程需要完成,对于熟悉Python的人来说可能更容易。哈哈 - Misty

2

最好的做法是这样的:

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

1

0

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接