Python 如何使用子类';基类中的函数属性? 概述
我有一个python类继承结构,其中大多数方法在基类中定义,而这些方法所依赖的大多数属性在子类中定义 基类大致如下所示:Python 如何使用子类';基类中的函数属性? 概述,python,object,inheritance,Python,Object,Inheritance,我有一个python类继承结构,其中大多数方法在基类中定义,而这些方法所依赖的大多数属性在子类中定义 基类大致如下所示: class Base(object): __metaclass__ = ABCMeta @abstractproperty def property1(self): pass @abstractproperty def property2(self): pass def method1(s
class Base(object):
__metaclass__ = ABCMeta
@abstractproperty
def property1(self):
pass
@abstractproperty
def property2(self):
pass
def method1(self):
print(self.property1)
def method2(self, val):
return self.property2(val)
class Child(Base):
property1 = 'text'
property2 = function
def function(val):
return val + 1
而子类如下所示:
class Base(object):
__metaclass__ = ABCMeta
@abstractproperty
def property1(self):
pass
@abstractproperty
def property2(self):
pass
def method1(self):
print(self.property1)
def method2(self, val):
return self.property2(val)
class Child(Base):
property1 = 'text'
property2 = function
def function(val):
return val + 1
其中,function
是一个如下所示的函数:
class Base(object):
__metaclass__ = ABCMeta
@abstractproperty
def property1(self):
pass
@abstractproperty
def property2(self):
pass
def method1(self):
print(self.property1)
def method2(self, val):
return self.property2(val)
class Child(Base):
property1 = 'text'
property2 = function
def function(val):
return val + 1
显然,上面的代码缺少细节,但结构反映了我真正的代码
问题
当我尝试在基类中使用method1
时,一切正常:
>>> child = Child()
>>> child.method1()
'text'
但是,尝试对method2
执行相同操作会出现错误:
>>> child = Child()
>>> child.method2(1) # expected 2
TypeError: method2() takes exactly 1 argument (2 given)
第二个传递的参数是子类本身
我想知道在调用method2
时是否有办法避免传递第二个Child
参数
尝试
我发现的一个解决方法是在基类中定义一个抽象方法,然后在子类中构建该函数,如下所示:
class Base(object):
__metaclass__ = ABCMeta
@abstractproperty
def property1(self):
pass
@abstractmethod
def method2(self, val):
pass
def method1(self):
print(self.property1)
但是,我更希望这个方法存在于基类中。有什么想法吗?提前谢谢 方法隐式地接收self
作为第一个参数,即使它似乎没有被传递。例如:
class C:
def f(self, x):
print(x)
C.f
接受两个参数,但通常只使用一个参数调用:
c = C()
c.f(1)
这样做的方式是,当您访问c.f
时,将创建一个“绑定”方法,该方法隐式地将c
作为第一个参数
如果将外部函数分配给类并将其用作方法,也会发生同样的情况
解决方案1
在子类中实现方法的通常方法是在那里显式地实现,而不是在外部函数中实现,因此,与您所做的不同,我将执行以下操作:
class Child(Base):
property1 = 'text'
# instead of: property2 = function
def property2(self, val):
return val + 1
解决方案2
如果你真的想把property2=function
放在类内(看不出原因)而function
放在类外,那么你必须照顾好self
:
class Child(Base):
property1 = 'text'
property2 = function
def function(self, val):
return val + 1
解决方案3
如果您想要上一个解决方案,但在函数中没有self
:
class Child(Base):
property1 = 'text'
def property2(self, val):
return function(val)
def function(val):
return val + 1
解决方案
将您的方法设置为静态:
class Child(Base)
property2 = staticmethod(function)
解释
正如zvone已经解释过的,隐式接收self
作为第一个参数。
要创建绑定方法,不必在类主体中定义它。
这:
将输出:
>>> <bound method foo of <__main__.Foo object at 0x014EC790>>
与此等效(*):
进一步改进
我建议对您的基础
类进行一个小的额外修改:
重命名property2
并将其标记为abstractproperty
,而不是abstractstaticmethod
(**)。
这将帮助同事(最终还有你自己)更好地理解在子类中需要什么样的实现
class Base(object):
__metaclass__ = ABCMeta
@abstractstaticmethod
def staticmethod1(self):
pass
(*)嗯,或多或少。前者实际上将函数
分配给属性2
,后者创建一个新的静态方法,委托给函数
(**)abstractstaticmethod
是从Python 3.3开始的,但由于您也在使用abstractproperty
,所以我希望保持一致。如果要将函数
分配给property2
,它必须有两个参数,因为当您调用self.property2(…)
时,它的\uuuu get\uuuu
方法将返回一个实例方法,尽管它没有在类中定义。如何使用property2=staticmethod(function)
将property2定义为staticmethod
?感谢@zvone的响应。所有这些解决方案都可以达到这个目的,但我认为@dudenr33使用staticmethod()
需要最少的代码来实现。除非有人看到这个实现有什么明显的问题,我想我会接受它的,很高兴听到它对你有用。我写了一个更详细的答案,解释了它是如何工作的以及为什么工作的。