Python:私有内部枚举类中的静态方法

Python:私有内部枚举类中的静态方法,python,enums,static-methods,Python,Enums,Static Methods,在名为Parser的类中实现名为“LineCode”的内部私有枚举类时遇到问题 LineCode:私有枚举类,它定义了6种类型的一般可能的代码行。我使用枚举实例化发送一个正则表达式模式,并在构造函数中编译它,然后将正则表达式匹配器作为类变量保存 解析器:解析编程语言,与什么语言无关。解析器使用行代码来标识行并相应地进行处理 问题:我无法从静态方法访问_LineCode的枚举成员。 我希望在_LineCode“matchLineCode(line)”中有一个静态方法,它从解析器接收字符串,然后按照

在名为Parser的类中实现名为“LineCode”的内部私有枚举类时遇到问题

LineCode:私有枚举类,它定义了6种类型的一般可能的代码行。我使用枚举实例化发送一个正则表达式模式,并在构造函数中编译它,然后将正则表达式匹配器作为类变量保存

解析器:解析编程语言,与什么语言无关。解析器使用行代码来标识行并相应地进行处理

问题:我无法从静态方法访问_LineCode的枚举成员。 我希望在_LineCode“matchLineCode(line)”中有一个静态方法,它从解析器接收字符串,然后按照以下逻辑迭代枚举成员:

  • 如果找到匹配项:返回枚举
  • 如果没有剩余枚举:返回None
这看起来并不简单,我无法访问enum成员来执行此操作

尝试:我尝试使用以下方法迭代枚举:

  • __行代码.\uuuuuuu成员\uuuuuuu.values()
  • 解析器.\uuuu行代码.\uuuuu成员\uuuuuu.values()
  • 两个都失败,因为它找不到_行代码

    理想情况下:行代码类必须是私有的,并且对于导入解析器的任何其他类都不可见。解析器必须使用LineCode类提供的静态方法返回枚举。我愿意接受任何解决这个问题或模仿这种行为的解决方案

    为了提高可读性,我省略了一些无关的解析器方法。 代码:

    我已经用Java实现了它,我想用Python重建同样的东西:

    private enum LineCode {
            STATEMENT("^(.*)" + Syntax.EOL + "\\s*$"), // statement line
            CODE_BLOCK("^(.*)" + Syntax.CODE_BLOCK + "\\s*$"), // code block open line
            CODE_BLOCK_END("^\\s*" + Syntax.CODE_BLOCK_END + "\\s*$"), // code block close line
            COMMENT_LINE("^\\s*" + Syntax.COMMENT + "(.*+)$"), // comment line
            BLANK_LINE("\\s*+$"); // blank line
    
            private final static int CONTENT_GROUP = 1;
    
            private Pattern pattern;
            private Matcher matcher;
    
            private LineCode(String regex) {
                pattern = Pattern.compile(regex);
            }
    
            boolean matches(String line) {
                matcher = pattern.matcher(line);
                return matcher.matches();
            }
    
            String lastMatch() {
                try {
                    return matcher.group(CONTENT_GROUP);
                } catch (IndexOutOfBoundsException e) {
                    return matcher.group();
                }
            }
        static LineCode matchLineCode(String line) throws    UnparsableLineException {
            for (LineCode lineType : LineCode.values())
                if (lineType.matches(line)) return lineType;
            throw new UnparsableLineException(line);
        }
    

    谢谢。

    您可以将
    staticmethod
    更改为
    classmethod
    ,这样传递给
    matchLineCode
    的第一个参数将是
    \u lineCode
    类,您可以对其进行迭代


    编辑 我决定添加一个更详细的解释,解释为什么使用
    @staticmethod
    装饰器的
    matchLineCode
    无法看到
    \u lineCode
    类。首先,我建议你阅读一些张贴在网站上的问题,以便讨论问题。主要区别在于
    classmethod
    知道定义方法的类,而
    staticmethod
    不知道。这并不意味着您无法从
    staticmethod
    中查看
    \uu lineCode
    类,它只是意味着您需要做更多的工作才能这样做

    按照您组织代码的方式,class
    \uu lineCode
    是class
    解析器的class属性。在python中,方法总是公共的,没有Java中的私有或受保护的类成员。但是,类属性名称(或实例属性名称)开头的双下划线表示该名称将被删除。这意味着在类
    解析器
    之外定义的任何函数都可以作为

    Parser._Parser__lineCode
    
    这意味着使用
    @staticmethod
    装饰器,您可以通过执行以下操作来迭代
    \uu lineCode

    @staticmethod
    def matchLineCode(line):
        for lineType in Parser._Parser__lineCode:
            if lineType.matches(line):
                return lineType
        return None
    

    但是,在我看来,使用
    @classmethod
    装饰器让函数知道
    \uu lineCode
    类更具可读性,也更容易理解。

    谢谢,它修复了它。显然,我对可能的属性不熟悉,我将对此进行研究。@Ben,我很高兴我的建议能有所帮助!我将添加一个更详细的解释,解释为什么您不能用
    staticmethod
    装饰器查看
    \uuuuu lineCode
    类。@BenA:变量/方法名的前导
    \uuuu
    应该很少使用,主要是为了帮助类和子类不会相互碰撞;“实现详细信息,请勿触摸”的约定是变量/方法名称的单个前导
    @staticmethod
    def matchLineCode(line):
        for lineType in Parser._Parser__lineCode:
            if lineType.matches(line):
                return lineType
        return None