Python:继承类函数(属性getter)不起作用

时间:2013-01-30 13:24:09

标签: python inheritance properties

请考虑以下代码:

class BaseClass(object):
    def _del_property(attr):
        """Abstract deller"""
        def del_attr(self):
            setattr(self, attr, None)
        return del_attr

    def _set_property(attr):
        """Abstract setter."""
        def set_attr(self, x):
            setattr(self, attr, x)            
        return set_attr

    def _get_property(attr):
        """Abstract getter"""
        def get_attr(self):
            getattr(self, attr)
        return get_attr

    _name = None
    name = property(fget=_get_property('_name'), fset=_set_property('_name'))


class Component(BaseClass):

    _material = None
    material = property(fget=_get_property('_material'), fset=_set_property('_material'), fdel=_del_property('_material'))

为什么不继承_get_property,_set_property和_del_property? 如何实现?

它应该适用于同一源文件中的派生类,以及单独文件中的派生类,它使用

导入此源文件
from filename import *

1 个答案:

答案 0 :(得分:2)

创建类时,会创建一个新的命名空间。 Python读取类块中的代码块,然后将信息传递给type(或相应的元类)。在这种情况下,python会抱怨,因为在设置Component类时,_get_property未在该范围内定义 - 也许BaseClass._get_property,但这可能不会像您想要的那样工作要么。

一个简单的解决方法是使这些函数模块级函数,因为类命名空间可以访问模块命名空间:

def _del_property(attr):
    """Abstract deller"""
    def del_attr(self):
        setattr(self, attr, None)
    return del_attr

def _set_property(attr):
    """Abstract setter."""
    def set_attr(self, x):
        setattr(self, attr, x)            
    return set_attr

def _get_property(attr):
    """Abstract getter"""
    def get_attr(self):
        getattr(self, attr)
    return get_attr


class BaseClass(object):

    _name = None
    name = property(fget=_get_property('_name'), fset=_set_property('_name'))


class Component(BaseClass):

    _material = None
    material = property(fget=_get_property('_material'), fset=_set_property('_material'), fdel=_del_property('_material'))

在我们创建课程时,或许看一下课程会更有启发性:

class BaseClass(object):

    def _del_property(attr):
        """Abstract deller"""
        def del_attr(self):
            setattr(self, attr, None)
        return del_attr

    print type(_del_property)
print type(BaseClass._del_property)

这将打印:

<type 'function'>
<type 'instancemethod'>

所以,你正在处理BaseClass内的常规函数​​,但在instancemethod之后它变为type


就个人而言,我只想创建一个便利功能:

def property_api(name,fget=True,fset=True,fdel=True):
    return property(fget=_get_property(name) if fget else None,
                    fset=_set_property(name) if fset else None,
                    fdel=_del_property(name) if fdel else None)

然后你可以使用它。如果您真的想要,您甚至可以将BaseClass作为staticmethod

 class BaseClass(object):
      property_api = staticmethod(property_api)

然后你的派生类看起来像:

 class DerivedClass(BaseClass):
      _material = None
      material = BaseClass.property_api('_material')