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

发布于 2024-11-25 23:29:40 字数 3070 浏览 6 评论 0原文

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

what is the python version of saying this.. this is in java

public static enum Operations {Add, Subtract, Multiply, Divide, None};

I am converting an entire program to python, i just cant figure out this part

heres my whole class

    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;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

终止放荡 2024-12-02 23:29:40

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

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

这会将 add 分配给 0,将 none 分配给 4。这是最干净的方法(并且它将保证您没有任何枚举)在此序列中,它们是相同的数字,并且您没有错过为其中一个数字分配某些内容。

Python doesn't have an enum class. It just does it using normal integers. The easiest way to make a template part of a class is to do the following:

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

Which will assign add to 0 and none to 4. This is the most clean way of doing it (and it will guarantee that you don't have any enums in this sequence that are the same number and that you haven't missed assigning something to one of the numbers.

甜柠檬 2024-12-02 23:29:40

您始终可以使用 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_

You can always use a 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

On newer Python versions, you can't assign to None, so I changed it to None_.

心房的律动 2024-12-02 23:29:40

在 Python 中,任何属性或方法都被视为公共的,除非您在其名称开头添加下划线。 这里是 Python 2.7 教程中的相关部分

Python 没有办法完全复制 static 的功能,但是您在类上定义的任何属性都将在实例中可见,就像 static 变量一样。只需在类定义中添加 attribute = value 就可以了。

您无法在 Python 中使值常量,但约定是使用UPPERCASE_IDENTIFIERS 来指示该意图。

枚举不存在。在 Python 中,普通字符串常量通常用于此目的。只需传递 "add" "subtract", "multiply", "divide"None< /code> 到你的函数。

例如,在你的解析器中

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

In Python any attribute or method is considered public unless you put underscores at the start of its name. Here is the relevant section in the Python 2.7 tutorial.

Python doesn't have a way of exactly duplicating the function of static, but any attributes you define on a class will be visible in instances in the same way as static variables are. Just attribute = value inside your class definition and you're fine.

You can't make values constant in Python, but the convention is to use UPPERCASE_IDENTIFIERS to indicate that intention.

Enums do not exist. In Python ordinary strings constants are usually used for this purpose. Just pass "add" "subtract", "multiply", "divide" or None to your function.

For example, in your parser

if (operator.equals("+"))
    op = Expression.Operations.Add;

would become

if operator == "+":
    op = "add"

and in your evaluator

if (op == Expression.Operations.Add)
    value = a + b;

would become

if op == "add"
    value = a + b
原来是傀儡 2024-12-02 23:29:40

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

A dict can provide the mapping between the symbol and the function. The operator module provides convenient access to the built-in functions used in expressions. Also, you can protect some attributes from getting accidentally modified by buggy code by making them read-only properties. Attempting to modify them will raise an AttributeError at run time. If someone really needs write access it's still available via the underscore prefixed variables, but that's a private interface.

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)
他是夢罘是命 2024-12-02 23:29:40

最好的方法是这样的:

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

best way to do it would be like:

class Operations:
    Add=1
    Subtract=2
    Multiply=3
    Divide=4
    None=5
请叫√我孤独 2024-12-02 23:29:40

java 中的枚举依赖于 http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern - 枚举在java中就像:Enum>。所以除非 python 支持这类东西,否则你可能必须使用类似的东西
类型安全枚举模式: http://java.sun.com/developer/Books/ effectivejava /第五章.pdf

enums in java rely on the http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern - enums in java are like: Enum>. so unless python supports that sort of thing you may have to use something like the
Typesafe Enum Pattern: http://java.sun.com/developer/Books/effectivejava/Chapter5.pdf

长途伴 2024-12-02 23:29:40

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

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

我如何在 Python 中表示“枚举”?

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

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

I like enums and I wish Python had an official enum of some sort.

Here is a link to another answer I wrote about Python enums:

How can I represent an 'Enum' in Python?

And here's a direct link to the recipe I recommend there:

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

孤云独去闲 2024-12-02 23:29:40

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

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

Python latest versions do have support for enum, just want to close the loop after reading all the above responses

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文