【问题标题】:Inheriting Python Class args from Super从 Super 继承 Python 类 args
【发布时间】:2012-12-11 06:38:36
【问题描述】:

我想从 Base 类继承 collection arg。怎么样?

class Base(object):
    def __init__(self, collection=None, classname=None):
        self.__collection__ = collection or self.__class__.__name__

class Thing(Base):
    def __init__(self, **kwargs):
        super(Thing, self).__init__()
        self.__dict__.update(kwargs)


t = Thing(collection='foobar')
t.__collection__

>>> 'Thing'

:(

【问题讨论】:

  • 别忘了接受答案。

标签: python class inheritance


【解决方案1】:

我通常不使用super()。我改为直接调用__init__ 函数。比如:

class Base(object):
    def __init__(self, collection=None, classname=None):
        self.__collection__ = collection or self.__class__.__name__

class Thing(Base):
    def __init__(self, **kwargs):
        #super(Thing, self).__init__()
        Base.__init__(self, **kwargs)
        #self.__dict__.update(kwargs)


t = Thing(collection='foobar')
print(t.__collection__)

应该产生你想要的。

【讨论】:

  • 这行得通,但我需要self.__dict__.update(kwargs),所以我可以在实例化时传入dict。 `t = Thing(collection='foobar', **{'other':'stuff'})
  • 在这种情况下,您需要 Base 类也接受 kwargs。类似def __init__(self, collection=None, classname=None, **kwargs)
【解决方案2】:

您只需要将kwargs“转发”到您的基类'__init__() 方法:

class Thing(Base):
    def __init__(self, **kwargs):
        super(Thing, self).__init__(**kwargs)
        self.__dict__.update(kwargs)

t = Thing(collection='foobar')
assert t.__collection__ == 'foobar'
assert t.__dict__.get('collection') == 'foobar'

您只是使用默认参数调用Base.__init__()

【讨论】:

  • 这行得通,但我需要self.__dict__.update(kwargs),所以我可以在实例化时传入dict。 `t = Thing(collection='foobar', **{'other':'stuff'})
【解决方案3】:

您在寻找super(Thing, self).__init__(**kwargs) 吗?这会将关键字参数传递给超类__init__

【讨论】:

    【解决方案4】:

    不要在实例变量的开头使用双下划线,并且避免在开头和结尾使用它们,因为双下划线在python中有特殊的含义。

    如果实例变量的标识符以双下划线开头,则它是“名称重整”以避免子类的命名空间中的冲突,因此self.__collections 实际上变成了self._Base__collections。 实例变量标识符开头和结尾的双下划线保留用于特殊方法和特殊名称(例如__add____class__)。

    实例变量应该以字母开头(例如collections)或单个下划线以表示它们是私有的(例如_collections

    无论如何,在您的示例中,您正在设置一个不存在的 collection 属性。如果您在 Base 类中将属性命名为 self.collection,它将正常工作。

    说清楚:

    >>> class Base(object):
    ...     def __init__(self, collection=None):
    ...             self.__collection__ = collection or self.__class__.__name__
    ... 
    >>> class Thing(Base):
    ...     def __init__(self, **kwargs):
    ...             super(Thing, self).__init__()
    ...             self.__dict__.update(kwargs)
    ... 
    >>> t = Thing(collection=3)   __dict__.update creates a new instance attribute
    >>> t.__collection__
    'Thing'
    >>> t.collection   # here it is
    3
    >>> t = Thing(**{'__collection__': 7})   #UGLY! Do not do this!!!
    >>> t.__collection__
    7
    

    【讨论】:

    • 更不用说少了 3 次击键!谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-02-11
    • 1970-01-01
    • 2016-02-25
    • 2011-04-09
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多