私はいくつかのクラス定義を動的に生成しようとしています(C++拡張をラップするため)。次の記述子は、help()を使用してフィールドのdocstringにアクセスしようとする場合を除いて正常に動作しますが、フィールド自体ではなく記述子のデフォルトのドキュメントを提供します。Python記述子で動的ドキュメントストリングを作成する
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)
1はhelp(class.field)
ためdescriptor.__doc__
を得ることができますどのように任意のアイデア私が助け(クラス名)を行うときしかし、それは記述子に渡されたドキュメンテーション文字列を取得します? これを回避し、doc文字列を記述子に格納する代わりに、docのgetter関数のようなものがありますか?
のような:
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)
UPDATE:実は私は__get__
のこの定義で開始 :
help(DerivedClass.a)
のPython:
def __get__(self, obj, dtype=None):
return obj.get_field(self.name)
私が言ったとき、これで問題があることでした私が電話しようとしていたことを示す例外を投げたNone.get_field
。したがってhelp()
は、メソッドをobj=None
とdtype=DerivedClass
と呼びます。そのため、obj = Noneおよびdtype!= NoneのときにFieldDescriptorインスタンスを返すことにしました。 help(xyz)
はxyz.__doc__
を表示しようとしていました。その論理によって、__get__
がdescriptor_instance
を返した場合、descriptor_instance.__doc__
はhelp()によって出力されます。これはクラス全体[help(DerivedClass)
]の場合ですが、[help(DerivedClass.a)
]という単一フィールドの場合はそうではありません。
私はそれがすべてあると確信していますが、間違ったヘルプ出力を与える呼び出しを明確にすることはできますか?コードを読んで期待したことを推測するのは大変です。 – alexis
jsbuenoが指摘しているように、ヘルプ(DerivedClass.a)はフィールドのドキュメントではなく、ディスクリプタのドキュメントを表示します(ディスクリプタ.__ doc__に保存されています)。 – subhacom