Я пытаюсь динамически генерировать определения классов (для упаковки расширения 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" выводит:
Doc is: field a in class DerivedClass Help on FieldDescriptor in module __main__ object: class FieldDescriptor(__builtin__.object) | Methods defined here: | | __get__(self, obj, dtype=None) | | __init__(self, name, doc='No documentation available.') | | __set__(self, obj, value) | | ---------------------------------------------------------------------- | Data descriptors defined here: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) Doc is: field a in class DerivedClass Doc is: field b in class DerivedClass Help on class DerivedClass in module __main__: class DerivedClass(TestClass) | Method resolution order: | DerivedClass | TestClass | __builtin__.object | | Data descriptors defined here: | | a | field a in class DerivedClass | | b | field b in class DerivedClass | | ---------------------------------------------------------------------- | Methods inherited from TestClass: | | __init__(self) | | get_field(self, name) | | set_field(self, name, value) | | ---------------------------------------------------------------------- | Data descriptors inherited from TestClass: | | __dict__ | dictionary for instance variables (if defined) | | __weakref__ | list of weak references to the object (if defined) Help on NoneType object: class NoneType(object) | Methods defined here: | | __hash__(...) | x.__hash__() hash(x) | | __repr__(...) | x.__repr__() repr(x)
Есть идеи, как получить descriptor.__doc__
за help(class.field)
? И есть ли способ обойти это и иметь что-то вроде функции получения для документа вместо необходимости хранить строку документа в дескрипторе?
нравиться:
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
. Таким образом, help()
вызывает метод __get__
с obj=None
и dtype=DerivedClass
. Вот почему я решил вернуть экземпляр FieldDescriptor, когда obj = None и dtype! = None. Мое впечатление было help(xyz)
попыток отобразить xyz.__doc__
. По этой логике, если __get__
возвращает descriptor_instance
, то descriptor_instance.__doc__
должен быть напечатан с помощью help (), что справедливо для всего класса [help(DerivedClass)
], но не для одного поля [help(DerivedClass.a)
].
help
python. В итоге я написал для этого специальную справочную функцию. Это была часть довольно сложного проекта, но код здесь: github.com/BhallaLab/moose-core/blob/master/python/moose/. Код интерфейса Python / C ++ находится вpymoose
каталоге того же репо. - person subhacom   schedule 04.07.2019