Pythonic在Python中重写Java代码的方法

Ash*_*osh 1 python java error-code

我必须在python中编写一个用Java编写的库.来自Java背景python让我有点困难.我坚持选择正确的pythonic方式做某事......

所以,我的java代码是这样的:

import java.util.Collection;

public abstract class MyEnumBaseClass
{
    protected int    value;
    protected String description = null;

    protected MyEnumBaseClass(int iValue, String iDescription)
    {
        value = iValue;
        description = iDescription;
    }

    public int getValue()
    {
        return value;
    }

    public String getDescription()
    {
        return description;
    }

    protected static MyEnumBaseClass getEnum(Collection<MyEnumBaseClass> iter, int value)
    {
        for (MyEnumBaseClass enumObj : iter)
        {
            if (enumObj.getValue() == value)
            {
                return enumObj;
            }
        }
        return null;
    }
}



import java.util.ArrayList;
import java.util.Collection;

public class MyEnumClass extends MyEnumBaseClass
{
    private final static Collection<MyEnumBaseClass> enumList   = new ArrayList<MyEnumBaseClass>();

    public final static int                          ERROR1     = 1;
    public final static int                          ERROR2     = 2;
    public final static int                          ERROR3     = 3;
    public final static int                          ERROR4     = 4;

    public final static MyEnumClass                  ErrorEnum1 = new MyEnumClass(ERROR1, "ERROR1");
    public final static MyEnumClass                  ErrorEnum2 = new MyEnumClass(ERROR2, "ERROR1");
    public final static MyEnumClass                  ErrorEnum3 = new MyEnumClass(ERROR3, "ERROR1");
    public final static MyEnumClass                  ErrorEnum4 = new MyEnumClass(ERROR4, "ERROR1");

    protected MyEnumClass(int iValue, String iDescription)
    {
        super(iValue, iDescription);
    }

    public static int getCount()
    {
        return enumList.size();
    }

    public static Collection<MyEnumBaseClass> getList()
    {
        return enumList;
    }

    public static MyEnumBaseClass getEnum(int value)
    {
        return getEnum(enumList, value);
    }
}
Run Code Online (Sandbox Code Playgroud)

我想在python中写一些东西.我知道两种语言都完全不同.我不想复制确切的代码,但我想在python中编写一些东西,它给了我Java代码给出的功能.

所以我想出了类似的东西:

# MODULE MYENUMBASECLASS:::

class MyEnumBaseClass(object):

    def __init__(self, iValue, iDescription, ui = None):
        self._value = iValue
        self._description = iDescription

    def getValue(self):
        return self._value

    def getDescription(self):
        return self._description

    @classmethod
    def getEnum(cls, value, itr):
        for enumObj in itr:
            if enumObj.getValue() == value:
                return enumObj
        return None


# MODULE: ENUMS:::
from MyEnumBaseClass import MyEnumBaseClass

__all__ = ["MyEnumClassConstants", "MyEnumClass", "MyEnums"]
_enumList = []

class MyEnumClassConstants(object):
    ERROR1 = 1
    ERROR2 = 2
    ERROR3 = 3
    ERROR4 = 4

class MyEnumClass(MyEnumBaseClass):
    def __init__(self, v, d, ui):
        global _enumList
        super(MyEnumClass, self).__init__(v, d, ui)
        _enumList.append(self)

    @staticmethod
    def getCount():
        return len(_enumList)

    @staticmethod
    def getList():
        return _enumList

    @classmethod
    def getEmum(cls, value, itr = None):
        return super(MyEnumClass, cls).getEnum(value, _enumList)


class MyEnums(object):
    ErrorEnum1 = MyEnumClass(MyEnumClassConstants.ERROR1, "ERROR1");
    ErrorEnum2 = MyEnumClass(MyEnumClassConstants.ERROR2, "ERROR2");
    ErrorEnum3 = MyEnumClass(MyEnumClassConstants.ERROR3, "ERROR3");
    ErrorEnum4 = MyEnumClass(MyEnumClassConstants.ERROR4, "ERROR4");
Run Code Online (Sandbox Code Playgroud)

我想知道:

  1. 这是正确的pythonic方式吗?

  2. 我想将ErrorEnum1,2,3,4和常量移出MyEnums类作为模块变量.但是这样我在我的所有变量中都会有一个很长的列表.当我在其他模块中导入Enums模块时,我也有变量名称冲突的风险(其他一些Enums2模块也可能有ErrorEnum1,2,3 ..但这不是一个大问题.我们总是可以使用Enums.ErrorEnum1和Enums2 .ErrorEnum1).我在想吗?

  3. 我知道这不是完美的(我的第一个python代码).所以我邀请你们给我一些想法.

谢谢

bra*_*zzi 5

好吧,我想你知道你的代码不是最优的,当然也不是可行的方法.另一个问题是我们不能说你如何"在python中写一些东西给我提供Java代码给出的功能",因为我们并不确切知道你想要做什么.也就是说,代码中有很多明显的Java偏见,可以毫无问题地删除:

  • 首先,为什么要有一个MyEnumBaseClass和一个MyEnumClass?你只能有一个.它将减少类的数量和模块的数量.即使你想扩展你的枚举,你会发现,在简化你的代码之后,你MyEnumClass会很简单,你可以毫无问题地扩展它.

  • 现在,请,没有吸气剂和二传手.你没有理由使用它们,因为你有属性.如果您的属性仅获取和设置值,请不要使用属性:

    class MyEnumClass(object):
        def __init__(self, value, description, ui = None):
            self.value = value
            self.description = description
    
    Run Code Online (Sandbox Code Playgroud)
  • 创建一个类只是为了保持类似常量的值,例如MyEnumClassConstantsMyEnums.只需在模块级别创建一些变量.让我们看看如何在下面的项目之后做到这一点.

  • 另外,为什么是getEnum()一种类方法呢?这可能只是一个功能,你不必担心冲突,因为它在一个模块内:

    def getEnum(value, itr):
        for enumObj in itr:
            if enumObj.value == value:
                return enumObj
        return None
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果您要使用序列号设置一些变量,您可能需要使用解包惯用法:

    (
        ERROR1,
        ERROR2,
        ERROR3,
        ERROR4
    ) = range(1, 5)
    
    Run Code Online (Sandbox Code Playgroud)
  • 这个成语也可以用来创建你的枚举列表:

    _enums = (
        ErrorEnum1,
        ErrorEnum2,
        ErrorEnum3,
        ErrorEnum4
    ) = (
        MyEnumClass(ERROR1, "ERROR1"),
        MyEnumClass(ERROR2, "ERROR2"),
        MyEnumClass(ERROR3, "ERROR3"),
        MyEnumClass(ERROR4, "ERROR4")
    )
    
    Run Code Online (Sandbox Code Playgroud)
  • 说实话,我很乐意_enums作为该模块的公共成员离开,但让我们用Java-itis轻松一下:P正如我们所做的那样getEnum(),让我们使用其他类方法:将它们声明为模块中的函数:

    def getCount():
        return len(_enums)
    
    def getList():
        return _enums
    
    Run Code Online (Sandbox Code Playgroud)
  • 我们甚至可以getEnum()通过更改默认参数来改进:

    def getEnum(value, itr=_enums):
        for enumObj in itr:
            if enumObj.value == value:
                return enumObj
        return None
    
    Run Code Online (Sandbox Code Playgroud)
  • 我也很乐意在__all__这里禁止宣言.唯一不属于接口的是_enums元组_,根据PEP-8,它的前面意味着它不应该在外部使用.但是让我们说它会留下来.您的模块有一个新接口,具有更多常量和功能:

    __all__ = ["MyEnumClass", "ERROR1", "ERROR2", "ERROR3", "ERROR4",
            "ErrorEnum1", "ErrorEnum2", "ErrorEnum3", "ErrorEnum4",
            "getCount", "getList", "getEnum"]
    
    Run Code Online (Sandbox Code Playgroud)

    MyEnumClass从界面中删除似乎更好,但是你可能想要使用它,所以我会离开它.请注意,该__all__也不会避免访问模块的其他组件.它只是改变了文档

最终结果将是这样的:

__all__ = ["MyEnumClass", "ERROR1", "ERROR2", "ERROR3", "ERROR4",
        "ErrorEnum1", "ErrorEnum2", "ErrorEnum3", "ErrorEnum4",
        "getCount", "getList", "getEnum"]

class MyEnumClass(object):
    def __init__(self, value, description, ui = None):
        self.value = value
        self.description = description

(
    ERROR1,
    ERROR2,
    ERROR3,
    ERROR4
) = range(1, 5)


_enums = (
    ErrorEnum1,
    ErrorEnum2,
    ErrorEnum3,
    ErrorEnum4
) = (
    MyEnumClass(ERROR1, "ERROR1"),
    MyEnumClass(ERROR2, "ERROR2"),
    MyEnumClass(ERROR3, "ERROR3"),
    MyEnumClass(ERROR4, "ERROR4")
)

def getCount():
    return len(_enums)

def getList():
    return _enums

def getEnum(value, itr=_enums):
    for enumObj in itr:
        if enumObj.value == value:
            return enumObj
    return None
Run Code Online (Sandbox Code Playgroud)

(已编辑)这实际上并不简单.如果我想创建的错误代码,我只会打造ERROR1,ERROR2等变量-没有阶级,没有功能,只是值的变量.实际上,甚至创建错误代码的想法似乎都是不合适的:你应该更喜欢创建异常,因为正如Python的Zen所说,错误永远不会无声地传递(或者,正如Eric Raymond的Unix哲学所说,当你必须失败时,就会吵闹并尽快).尽管如此,我敢打赌,我所做的改变可以让你更精确地编写Python.

你可能会觉得用这种方式做事情,但相信我,这是最好的方式.有些人可能会在某些方面与我不同意,但这个想法就是提出来的.我主要是一个Java开发人员,但跳到语言的音乐是很重要的 - 不要试图强迫外国概念.

最后,一些重要的参考:

  • PEP-20 - Python的禅宗:在Python和Python开发中的核心价值列表.
  • PEP-8 - Python的样式指南.读它现在.
  • Python不是Java - 关于避免Python中不适当的Java习惯的最佳指南之一.