繁体   English   中英

__init __()的“私有”参数?

[英]“Private” arguments to __init__()?

我有一个类在实例化时采用单个参数a ,它存储在_a属性中。 对于许多方法(运算符),我还需要在结果上设置_b属性。 目前这是以直截了当的方式实施的:

class SomeClass(object):
    def __init__(self, a=0):
        self._a = a
        self._b = 0

    def __add__(self, other):
        result = self.__class__()
        result._b = self._a + other._a
        return result

现在,我有一些像_b这样的成员,比如_c_d ,所以__add__将需要为这些属性中的每一个添加额外的行。 能够在对象实例化上传递这些将导致更清晰的代码:

class SomeClass(object):
    def __init__(self, a=0, _b=0):
        self._a = a
        self._b = 0

    def __add__(self, other):
        return self.__class__(_b=self._a + other._a)

不过,我不希望用户传递值的所有参数,除了a作为_b_c_d是实现细节。 我可以简单地在docstring中声明不要传递多个参数。 使用下划线在“私有”属性之前是为了反映这一点。

或者,通过提供第二个私有构造函数,我可以尝试让用户更难行为:

class SomeClass(object):
    def __init__(self, a=0):
        self._a = a
        self._init()

    def _init(self, _b=0):
        self._b = _b

    @classmethod
    def _constructor(cls, a, _b):
        obj = cls(a)
        obj._init(b)
        return obj

    def __add__(self, other):
        return self.__class__._constructor(_b=self._a + other._a)

我认为这是一个相当笨重的解决方案。

什么是解决这个问题的首选方法? 还有其他更优雅的解决方案吗? 这真的是一个问题; 我应该使用第一个选项并最终获得更多代码行吗?

通过python世界, _下划线惯例清晰而普遍。

您记录了您的'public'属性,只使用带有下划线的默认参数到__init__方法。 把事情简单化。

如果有人通过使用这些私有参数搞砸一个类,你不会阻止它们,而不是Python。

要整理一下,你可以在__init__之前设置_b

class SomeClass(object):
    _b = 0
    def __init__(self, a=0):
        self._a = a

    def __add__(self, other):
        result = self.__class__()
        result._b = self._a + other._a
        return result

或者,如果有大量私有变量,将它们放入列表并做一些魔术?

class SomeClass(object):
    calculated_vars = ['_b'] # All your calculated variables

    def __init__(self, a=0):
        self._a = a

    def __getattr__(self, k):
        if k in self.calculated_vars:
            return 0 # Default value for calculated variables
        else:
            raise AttributeError('{} not found'.format(k))

    def __add__(self, other):
        result = self.__class__()
        result._b = self._a + other._a
        return result

if __name__ == '__main__':
    i = SomeClass(1)
    print '_a attr: ', i._a # 1
    print '_b attr: ', i._b # 0 (Default value)
    print '_c attr: ', i._c # AttributeError: _c not found

    i2 = SomeClass(3)
    i3 = i + i2
    print '_b attr: ', i3._b # 4 (Calculated value)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM