gpt4 book ai didi

java - 在 Python 中重写 Java 代码的 Pythonic 方式

转载 作者:太空宇宙 更新时间:2023-11-04 09:14:32 25 4
gpt4 key购买 nike

我必须在 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);
}
}

我想用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");

我想知道:
  • 这是正确的pythonic方式吗?
  • 我想将 ErrorEnum1,2,3,4 和常量移出 MyEnums 类作为模块变量。但是这样我的 中就会有一个很长的列表。全部 多变的。当我在其他模块中导入 Enums 模块时,我也有变量名冲突的风险(其他一些 Enums2 模块也可能有 ErrorEnum1,2,3.. 但这不是一个大问题。我们总是可以使用 Enums.ErrorEnum1 和 Enums2 .ErrorEnum1)。我想对了吗?
  • 我知道这并不完美(我的第一个 python 代码)。所以我邀请你们给我一些想法。

  • 谢谢

    最佳答案

    好吧,我想你知道你的代码不是最优的,当然是 不是 要走的路。另一个问题是我们不能说你怎么能“用python写一些东西给我Java代码提供的功能”,因为我们不知道你到底想做什么。也就是说,您的代码中有很多明显的 Java 偏见,可以毫无问题地删除:

  • 一、为什么要有MyEnumBaseClassMyEnumClass ?你只能拥有一个。它将减少类的数量和模块的数量。即使您想扩展您的枚举,您也会看到,在简化代码之后,您的 MyEnumClass将非常简单,您可以毫无问题地扩展它。
  • 现在,请不要使用 getter 和 setter。你没有理由使用它们,因为你有属性。如果您的属性只会获取和设置值,请不要使用属性:
    class MyEnumClass(object):
    def __init__(self, value, description, ui = None):
    self.value = value
    self.description = description
  • 创建一个类只是为了保存类似常量的值真的很丑陋,例如MyEnumClassConstantsMyEnums .只需在模块级别创建一些变量。让我们在下面的项目之后看看如何做到这一点。
  • 另外,为什么是 getEnum()上课方法?这可能只是一个函数,您不必担心冲突,因为它位于模块内部:
    def getEnum(value, itr):
    for enumObj in itr:
    if enumObj.value == value:
    return enumObj
    return None
  • 如果您要设置一些带有序号的变量,您可能需要使用 unpacking idiom :
    (
    ERROR1,
    ERROR2,
    ERROR3,
    ERROR4
    ) = range(1, 5)
  • 这个成语也可以用来创建你的枚举列表:
    _enums = (
    ErrorEnum1,
    ErrorEnum2,
    ErrorEnum3,
    ErrorEnum4
    ) = (
    MyEnumClass(ERROR1, "ERROR1"),
    MyEnumClass(ERROR2, "ERROR2"),
    MyEnumClass(ERROR3, "ERROR3"),
    MyEnumClass(ERROR4, "ERROR4")
    )
  • 老实说,我很乐意离开_enums作为模块的公共(public)成员,但让我们轻松处理您的 Java-itis :P 正如我们对 getEnum() 所做的那样,让我们处理其他类方法:将它们声明为模块中的函数:
    def getCount():
    return len(_enums)

    def getList():
    return _enums
  • 我们甚至可以改进 getEnum()通过更改默认参数:
    def getEnum(value, itr=_enums):
    for enumObj in itr:
    if enumObj.value == value:
    return enumObj
    return None
  • 我也很乐意禁止 __all__在这里声明。唯一不属于界面一部分的是_enums。元组,它前面是 _其中,根据PEP-8 , 表示它不应该在外部使用。但让我们说它会留下来。你的模块有一个新的接口(interface),有更多的常量和函数:
    __all__ = ["MyEnumClass", "ERROR1", "ERROR2", "ERROR3", "ERROR4",
    "ErrorEnum1", "ErrorEnum2", "ErrorEnum3", "ErrorEnum4",
    "getCount", "getList", "getEnum"]

    似乎最好删除 MyEnumClass从界面,但好吧,你可能想使用它,所以我会离开它。请注意,__all__ value 不会避免访问模块的另一个组件。它只是更改了文档

  • 最终结果将是这样的:
    __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

    (已编辑)这真的没那么简单。如果我要创建错误代码,我只会创建 ERROR1 , ERROR2等变量 - 没有类,没有函数,只有变量中的值。实际上,即使创建错误代码的想法似乎也不合适:您应该更喜欢创建异常,因为正如 Python 之禅所说, errors should never pass silently (或者,正如 Eric Raymond 的 Unix 哲学所说, when you must fail, fail noisily and as soon as possible)。尽管如此,我敢打赌,我所做的更改可以让您对编写 Python 有更准确的了解。

    你可能会觉得这样做事很痒,但相信我,这是最好的方法。有些人可能在某些方面不同意我的观点,但这个想法是提出的。我主要是一名 Java 开发人员,但跟随语言的音乐起舞很重要——不要试图将外国概念强加于其中。

    最后,一些重要的引用资料:
  • PEP-20 - Python 的禅宗:用 Python 和 Python 开发的核​​心值(value)观有点诗意。
  • PEP-8 - Python 的风格指南。立即阅读。
  • Python is not Java - 关于避免 Python 中不恰当的 Java 习惯的最佳指南之一。
  • 关于java - 在 Python 中重写 Java 代码的 Pythonic 方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11215682/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com