定义实例变量时的最佳实践

2024-06-26 13:44:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我对Python还不太熟悉,有一个关于以下类的问题:

class Configuration:
    def __init__(self):
        parser = SafeConfigParser()
        try:
            if parser.read(CONFIG_FILE) is None:
                raise IOError('Cannot open configuration file')
        except IOError, error:
            sys.exit(error)
        else:
            self.__parser = parser
            self.fileName = CONFIG_FILE

    def get_section(self):
        p = self.__parser
        result = []
        for s in p.sections():
            result.append('{0}'.format(s))
        return result

    def get_info(self, config_section):
        p = self.__parser
        self.section = config_section
        self.url = p.get(config_section, 'url')
        self.imgexpr = p.get(config_section, 'imgexpr')
        self.imgattr1 = p.get(config_section, 'imgattr1')
        self.imgattr2 = p.get(config_section, 'imgattr2')
        self.destination = p.get(config_section, 'destination')
        self.createzip = p.get(config_section, 'createzip')
        self.pagesnumber = p.get(config_section, 'pagesnumber')

在另一个函数get_info中添加更多的实例变量可以吗?还是在构造函数中定义所有实例变量是最佳实践?如果我到处定义新的实例变量,就不会产生意面代码吗?

编辑:我使用这个代码和一个简单的图像刮刀。通过get_section我返回配置文件中的所有部分,然后遍历这些部分以访问从中获取图像的每个站点。对于每次迭代,我都会调用get_section,以获取配置文件中每个部分的配置设置。 如果有人能想出别的办法,那就好了!谢谢!


Tags: 实例selfinfoconfigparserurlgetdef
2条回答

我肯定会在__init__中声明所有实例变量。不这样做会增加复杂性和潜在的意外副作用。

为了提供David Hall在访问方面的另一种观点,这是来自Google Python style guide

Access Control:

If an accessor function would be trivial you should use public variables instead of accessor functions to avoid the extra cost of function calls in Python. When more functionality is added you can use property to keep the syntax consistent

On the other hand, if access is more complex, or the cost of accessing the variable is significant, you should use function calls (following the Naming guidelines) such as get_foo() and set_foo(). If the past behavior allowed access through a property, do not bind the new accessor functions to the property. Any code still attempting to access the variable by the old method should break visibly so they are made aware of the change in complexity.

From PEP8

For simple public data attributes, it is best to expose just the attribute name, without complicated accessor/mutator methods. Keep in mind that Python provides an easy path to future enhancement, should you find that a simple data attribute needs to grow functional behavior. In that case, use properties to hide functional implementation behind simple data attribute access syntax.

Note 1: Properties only work on new-style classes.

Note 2: Try to keep the functional behavior side-effect free, although side-effects such as caching are generally fine.

Note 3: Avoid using properties for computationally expensive operations; the attribute notation makes the caller believe that access is (relatively) cheap.

Python不是java/C#,它对代码的外观和编写有很强的想法。如果您是用python编写的,那么让它看起来像python是有意义的。其他人将能够更容易地理解您的代码,您也将能够更好地理解其他python代码。

我更喜欢在构造函数中设置所有实例变量,而不是使用像get_info()这样的函数来将类置于有效状态。

对于只通过调用方法(如get_info())来实例化的公共实例变量,可以创建一个要使用的类。

如果您担心某些配置值并不总是需要的,而且计算成本很高(我猜这就是为什么您有get_info(),允许延迟执行),那么我会考虑将该配置子集重构为第二个类,或者引入properties或返回值的函数。

使用properties或get-style函数,可以鼓励类的使用者通过定义的接口并改进封装1

一旦对实例变量进行了封装,您就可以选择做一些事情,而不仅仅是抛出一个NameError异常——您可以自己调用get_info(),或者抛出一个自定义异常。


1.您不能用Python提供100%的封装,因为由前导双下划线表示的私有实例变量仅按约定是私有的

相关问题 更多 >