Python устанавливает строку документации и получает имя метода динамически сгенерированного метода класса

Я пытаюсь получить/установить имя и строку документации динамически созданных методов класса следующим образом, но у меня возникли проблемы с выяснением того, как именно это сделать:

import sys
import inspect

class test(object):
    pass

@classmethod
def genericFunc(cls, **kwargs):
    print "function:", (inspect.stack()[0][3])
    print "kwargs:", kwargs

function_list = ['myF1', 'myF2']
for func in function_list:
    setattr(test, func, genericFunc)
    #set docstring for func here?

if __name__ == '__main__':
    x = test()
    print "docstring:", x.myF1.__doc__
    x.myF1(arg1="foo")
    y = test()
    print "docstring:", y.myF2.__doc__
    y.myF2(arg1="foo", arg2="bar")
    sys.exit()

В настоящее время выход:

docstring: None
function: genericFunc
kwargs: {'arg1': 'foo'}
docstring: None
function: genericFunc
kwargs: {'arg1': 'foo', 'arg2': 'bar'}

То, что я хотел бы иметь, это:

docstring: description of myF1
function: myF1
kwargs: {'arg1': 'foo'}
docstring: description of myF2
function: myF2
kwargs: {'arg1': 'foo', 'arg2': 'bar'}

В цикле for я попытался выполнить setattr(test.func, "__doc__", "description of %s" % func), что привело к исключению AttributeError (тип объекта «test» не имеет атрибута «func»), и если я жестко закодировал «test.myF1» вместо «test.func», я получаю AttributeError для атрибута '__doc__' метода экземпляра не доступен для записи.

Наконец, inspect.stack() возвращает «genericFunc» вместо имени динамической функции («myF1» или «myF2»), возможно ли получить/установить последнее, чтобы я мог проверить значение метода __name__ в genericFunc выполнять определенные действия в зависимости от его значения?


person k4otix    schedule 01.10.2014    source источник


Ответы (1)


Сама ваша общая функция не имеет строки документации. Это отлично работает для меня, когда я добавляю строку документации:

    import inspect

    class test(object):
        pass

    @classmethod
    def genericFunc(cls, **kwargs):
        """ I'm a docstring"""
        print "function:", (inspect.stack()[0][3])
        print "kwargs:", kwargs

    function_list = ['myF1', 'myF2']
    for func in function_list:
        setattr(test, func, genericFunc)
        #set docstring for func here?

    if __name__ == '__main__':
        x = test()
        print "docstring:", x.myF1.__doc__
        x.myF1(arg1="foo")
        y = test()
        print "docstring:", y.myF2.__doc__
        y.myF2(arg1="foo", arg2="bar")

Кроме того, почему sys.exit() в конце? В результате получаю:

docstring:  I'm a docstring
function: genericFunc
kwargs: {'arg1': 'foo'}
docstring:  I'm a docstring
function: genericFunc
kwargs: {'arg1': 'foo', 'arg2': 'bar'}
person Adam Hughes    schedule 01.10.2014
comment
corerct, но эта строка документации будет статической/одинаковой для myF1, myF2 и любых других функций, которые я добавляю в function_list. Я бы хотел, чтобы строка документации была динамической и включала имя функции. sys.exit() не нужен, просто привычка. - person k4otix; 01.10.2014
comment
Что-то вроде этого недостаточно: print docstring:, x.myF1.__name__ + x.myF1.__doc__ - person Adam Hughes; 01.10.2014
comment
x.myF1.__name__ возвращает genericFunc, а не myF1 или myF2. И мне нужно иметь возможность получить это значение из GeneralFunc. - person k4otix; 01.10.2014