请考虑以下代码:
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 *
答案 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')