python:具有staticmethods的类vs具有全局变量的模块

Bak*_*zik 5 python singleton static-methods module global-variables

我正在研究这个Python模块,它由几个文件组成.这些文件实际上很少是独立的,并且意味着要做一个非常具体的工作.我知道这样一个事实:这些文件只有一个实例(模块?),而且不多,因为这种工作是顺序的,只需要一次.

让我们以CXXParser我目前正在构建的这个模块为例:

例程简单明了 - 获取c ++文件,解析它,并将其"转换"为其他内容.由于我来自c ++世界,我立即开始在Python中寻找静态方法和单例.对于这个例子的使用,我有'public' parse函数,以及这个模块的许多'内部'函数,它实际上解析了文件.

我想知道,"Pythonic"的做法是什么?我开始四处寻找正确的方法,但只是感到困惑.因为我想到了单身 - 我看到了这个问题,并且从阅读答案开始,我开始在模块级实现它.但是,再一次,我观看Python核心开发人员Raymond Hettinger的几个视频,并且他提到 - 几次 - 全局变量都很糟糕,并且最好使用类级变量.

这些是我目前面临的两个选择:

A.使用classmethods类:

#cxxparser.py
class CXXParser(object):
    filename = ''
    cflags   = ''
    translation_unit = None

    def __init__(self, filename, cflags = None):
        super(CXXParser, self).__init__()
        filename = filename
        if cflags:
             cflags = cflags

    @classmethod
    def get_tu(cls):
        'get the tu from the file'
        return tu

    @classmethod
    def parse(cls):
        ...
        #call some inner functions
        #for example:
        translation_unit = cls.get_tu()
Run Code Online (Sandbox Code Playgroud)

并从另一个模块使用:

from cxxparser import CXXParser
cxxparser = CXXParser('Foo.c')
cxxparser.parse()
Run Code Online (Sandbox Code Playgroud)

B.使用模块级函数,使用全局变量:

#cxxparser.py
translation_unit = None
filename = ''

def get_tu(file):
    'get the tu from the file'
    return tu

def parse(filename='', cflags = None):
    global translation_unit
    global filename

    filename = filename
    if cflags:
         cflags = cflags
    ...
    #call some other functions
    translation_unit = get_tu(filename)
Run Code Online (Sandbox Code Playgroud)

并从另一个模块使用:

import cxxparser
cxxparser.parse('Foo.C')
Run Code Online (Sandbox Code Playgroud)

PS - 我试图尽我所能阅读它,并遇到了这些问题 - module-function-vs-staticmethod-vs-classmethod-vs-no-decorators-which-idiom-is?,python-class-design-staticmethod-vs-method,但即使在阅读了更多这些之后 - 我仍然无法确定在我的情况下最好的方法.任何帮助将不胜感激.

blh*_*ing 0

global在函数中使用该语句来允许修改全局变量在 Python 中是非常不受欢迎的。

由于filenamecflags特定于实例的属性,因此将方法改为实例方法更有意义,以便允许为不同的文件和/或不同的标志实例化不同的解析器实例:

class CXXParser:
    def __init__(self, filename, cflags = None):
        super().__init__()
        self.filename = filename
        self.cflags = cflags
        self.translation_unit = None

    def get_tu(self):
        # get tu from self.filename
        ...
        return tu

    def parse(self):
        ...
        self.translation_unit = cls.get_tu()
Run Code Online (Sandbox Code Playgroud)