我正在尝试动态生成一些类定义(用于包装 C++ 扩展)。以下描述符工作正常,除非我尝试使用 help() 访问字段的文档字符串,它为描述符提供默认文档,而不是它自己的字段。但是,当我执行帮助(类名)时,它会检索传递给描述符的文档字符串:
class FieldDescriptor(object):
def __init__(self, name, doc='No documentation available.'):
self.name = name
self.__doc__ = doc
def __get__(self, obj, dtype=None):
if obj is None and dtype is not None:
print 'Doc is:', self.__doc__
return self
return obj.get_field(self.name)
def __set__(self, obj, value):
obj.set_field(self.name, value)
class TestClass(object):
def __init__(self):
self.fdict = {'a': None, 'b': None}
def get_field(self, name):
return self.fdict[name]
def set_field(self, name, value):
self.fdict[name] = value
fields = ['a', 'b']
def define_class(class_name, baseclass):
class_obj = type(class_name, (baseclass,), {})
for field in fields:
setattr(class_obj, field, FieldDescriptor(field, doc='field %s in class %s' % (field, class_name)))
globals()[class_name] = class_obj
if __name__ == '__main__':
define_class('DerivedClass', TestClass)
help(DerivedClass.a)
help(DerivedClass)
v = DerivedClass()
help(v.a)
“python test.py”打印:
文档是:类 DerivedClass 中的字段 a 模块 __main__ 对象中 FieldDescriptor 的帮助: 类 FieldDescriptor(__builtin__.object) | 此处定义的方法: | | __get__(self, obj, dtype=None) | | __init__(self, name, doc='没有可用的文档。') | | __set__(self, obj, value) | | -------------------------------------------------- -------------------- | 此处定义的数据描述符: | | __dict__ | 实例变量的字典(如果已定义) | | __weakref__ | 对象的弱引用列表(如果已定义) 文档是:类 DerivedClass 中的字段 a 文档是:DerivedClass 类中的字段 b 模块 __main__ 中的 DerivedClass 类的帮助: 类派生类(TestClass) | 方法解析顺序: | 派生类 | 测试类 | __builtin__.object | | 此处定义的数据描述符: | | 一个 | 类 DerivedClass 中的字段 a | | b | DerivedClass 类中的字段 b | | -------------------------------------------------- -------------------- | 从 TestClass 继承的方法: | | __在自身) | | get_field(自我,姓名) | | set_field(自我,姓名,价值) | | -------------------------------------------------- -------------------- | 继承自 TestClass 的数据描述符: | | __dict__ | 实例变量的字典(如果已定义) | | __weakref__ | 对象的弱引用列表(如果已定义) 关于 NoneType 对象的帮助: 类无类型(对象) | 此处定义的方法: | | __hash__(...) | x.__hash__() 哈希(x) | | __repr__(...) | x.__repr__() 代表(x)
知道如何获得descriptor.__doc__
forhelp(class.field)
吗?有没有办法绕过这个并为 doc 提供一个 getter 函数,而不必将 doc 字符串存储在描述符中?
喜欢:
class FieldDescriptor(object):
def __init__(self, name, doc='No documentation available.'):
self.name = name
self.__doc__ = doc
def __get__(self, obj, dtype=None):
if obj is None and dtype is not None:
print 'Doc is:', self.__doc__
return self
return obj.get_field(self.name)
def __set__(self, obj, value):
obj.set_field(self.name, value)
# This is what I'd like to have
def __doc__(self, obj, dtype):
return dtype.generate_docstring(self.name)
更新:实际上我从以下定义开始__get__
:
def __get__(self, obj, dtype=None):
return obj.get_field(self.name)
问题在于,当我说:
help(DerivedClass.a)
Python 抛出了一个异常,表明我正在尝试调用None.get_field
. 因此使用andhelp()
调用该__get__
方法。这就是为什么我决定在 obj=None 和 dtype!=None 时返回 FieldDescriptor 实例。我的印象是试图展示。按照这个逻辑,如果返回,那么应该由 help() 打印,整个类 [ ] 都是这种情况,但单个字段 [ ] 不是这种情况。obj=None
dtype=DerivedClass
help(xyz)
xyz.__doc__
__get__
descriptor_instance
descriptor_instance.__doc__
help(DerivedClass)
help(DerivedClass.a)