Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用子类';基类中的函数属性? 概述_Python_Object_Inheritance - Fatal编程技术网

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

我有一个python类继承结构,其中大多数方法在基类中定义,而这些方法所依赖的大多数属性在子类中定义

基类大致如下所示:

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()
需要最少的代码来实现。除非有人看到这个实现有什么明显的问题,我想我会接受它的,很高兴听到它对你有用。我写了一个更详细的答案,解释了它是如何工作的以及为什么工作的。