Как печатать Docstring функции python внутри самой функции?
Я хочу напечатать docstring функции python внутри самой функции.
например,
def my_function(self):
"""Doc string for my function."""
# print the Docstring here.
В данный момент я делаю это непосредственно после определения my_function
.
print my_function.__doc__
Но скорее позвольте функции делать это сама.
Я попытался вызвать print self.__doc__
print self.my_function.__doc__
и print this.__doc__
внутри my_function, но это не сработало.
Ответы
Ответ 1
def my_func():
"""Docstring goes here."""
print my_func.__doc__
Это будет работать до тех пор, пока вы не измените объект, связанный с именем my_func
.
new_func_name = my_func
my_func = None
new_func_name()
# doesn't print anything because my_func is None and None has no docstring
Ситуации, в которых вы делаете это, довольно редки, но они происходят.
Однако, если вы пишете декоратор следующим образом:
def passmein(func):
def wrapper(*args, **kwargs):
return func(func, *args, **kwargs)
return wrapper
Теперь вы можете сделать это:
@passmein
def my_func(me):
print me.__doc__
И это гарантирует, что ваша функция получает ссылку на себя (аналогичную self
) в качестве своего первого аргумента, поэтому она всегда может получить docstring правильной функции. Если используется метод, обычный self
становится вторым аргументом.
Ответ 2
Это должно работать (в моих тестах оно также включает вывод). Вероятно, вы можете использовать __doc__
вместо getdoc, но мне это нравится, так что я только что использовал. Кроме того, это не требует, чтобы вы знали имена класса/метода/функции.
Примеры как для класса, так и для метода. Скажите, если это не то, что вы искали:)
from inspect import *
class MySelfExplaningClass:
"""This is my class document string"""
def __init__(self):
print getdoc(self)
def my_selfexplaining_method(self):
"""This is my method document string"""
print getdoc(getattr(self, getframeinfo(currentframe()).function))
explain = MySelfExplaningClass()
# Output: This is my class document string
explain.my_selfexplaining_method()
# Output: This is my method document string
def my_selfexplaining_function():
"""This is my function document string"""
print getdoc(globals()[getframeinfo(currentframe()).function])
my_selfexplaining_function()
# Output: This is my function document string
Ответ 3
Это работает:
def my_function():
"""Docstring for my function"""
#print the Docstring here.
print my_function.__doc__
my_function()
в Python 2.7.1
Это также работает:
class MyClass(object):
def my_function(self):
"""Docstring for my function"""
#print the Docstring here, either way works.
print MyClass.my_function.__doc__
print self.my_function.__doc__
foo = MyClass()
foo.my_function()
Это, однако, не будет работать само по себе:
class MyClass(object):
def my_function(self):
"""Docstring for my function"""
#print the Docstring here.
print my_function.__doc__
foo = MyClass()
foo.my_function()
NameError: глобальное имя 'my_function' не определено
Ответ 4
Вы задали свой вопрос как метод класса, а не функцию. Пространства имен важны здесь. Для функции print my_function.__doc__
отлично, так как my_function находится в глобальном пространстве имен.
Для метода класса тогда будет print self.my_method.__doc__
.
Если вы не хотите указывать имя метода, а скорее передаете ему переменную, вы можете использовать встроенные функции hasattr (объект, атрибут) и getattr (obj, attr), которые выполняют как говорят они, позволяя вам передавать переменные со строками, являющимися именем метода. например.
class MyClass:
def fn(self):
"""A docstring"""
print self.fn.__doc__
def print_docstrings(object):
for method in dir( object ):
if method[:2] == '__': # A protected function
continue
meth = getattr( object, method )
if hasattr( meth , '__doc__' ):
print getattr( meth , '__doc__' )
x = MyClass()
print_docstrings( x )
Ответ 5
Попробуйте:
class MyClass():
# ...
def my_function(self):
"""Docstring for my function"""
print MyClass.my_function.__doc__
# ...
(*) Произошла двоеточие (:
) после my_function()
Ответ 6
Существует довольно простой способ сделать это, о котором никто еще не упомянул:
import inspect
def func():
"""Doc string"""
print inspect.getdoc(func)
И это делает то, что вы хотите.
Здесь нет ничего интересного. Все, что происходит, заключается в том, что, выполняя func.__doc__
в функции, исправляет разрешение атрибута достаточно долго, чтобы смотреть вверх __doc__
на нем работает так, как вы ожидали.
Я использую это с docopt для консольных точек доступа script.
Ответ 7
Как отмечалось много раз, использование имени функции - это динамический поиск в каталоге globals(). Он работает только в модуле определения и только для глобальной функции. Если вы хотите узнать строку doc для функции-члена, вам также нужно будет искать путь от имени класса, что довольно громоздко, так как эти имена могут быть довольно длинными:
def foo():
""" this is foo """
doc = foo.__doc__
class Foo:
def bar(self):
""" this is bar """
doc = Foo.bar.__doc__
эквивалентно
def foo():
""" this is foo """
doc = globals()["foo"].__doc__
class Foo:
def bar(self):
""" this is bar """
doc = globals()["Foo"].bar.__doc__
Если вы хотите посмотреть строку документа вызывающего, это не будет работать, так как ваш помощник по печати может жить в совершенно другом модуле с совершенно другим словарем globals(). Единственный правильный выбор - посмотреть в стек стека, но Python не дает вам исполняемый объект функции, он имеет ссылку только на объект кода f_code. Но продолжайте движение, так как есть ссылка на "f_globals" этой функции. Таким образом, вы можете написать функцию, чтобы получить код вызывающего пользователя, как этот, и в качестве варианта от него вы получаете свою собственную строку документа.
import inspect
def get_caller_doc():
frame = inspect.currentframe().f_back.f_back
for objref in frame.f_globals.values():
if inspect.isfunction(objref):
if objref.func_code == frame.f_code:
return objref.__doc__
elif inspect.isclass(objref):
for name, member in inspect.getmembers(objref):
if inspect.ismethod(member):
if member.im_func.func_code == frame.f_code:
return member.__doc__
и отпустите его, чтобы проверить:
def print_doc():
print get_caller_doc()
def foo():
""" this is foo """
print_doc()
class Foo:
def bar(self):
""" this is bar """
print_doc()
def nothing():
print_doc()
class Nothing:
def nothing(self):
print_doc()
foo()
Foo().bar()
nothing()
Nothing().nothing()
# and my doc
def get_my_doc():
return get_caller_doc()
def print_my_doc():
""" showing my doc """
print get_my_doc()
print_my_doc()
приводит к этому выводу
this is foo
this is bar
None
None
showing my doc
На самом деле, большинство людей хотят, чтобы их собственная строка документа только передавала ее в качестве аргумента, но вызываемая вспомогательная функция может сама по себе разобраться. Я использую это в своем unittest-коде, где это иногда удобно заполнять некоторые журналы или использовать строку doc в качестве тестовых данных. Причина, по которой представленный get_caller_doc() ищет только глобальные тестовые функции и функции-члены тестового класса, но я думаю, этого достаточно для большинства людей, которые хотят узнать о строке документа.
class FooTest(TestCase):
def get_caller_doc(self):
# as seen above
def test_extra_stuff(self):
""" testing extra stuff """
self.createProject("A")
def createProject(self, name):
description = self.get_caller_doc()
self.server.createProject(name, description)
Для определения правильного get_frame_doc (фрейма) с sys._getframe (1) остается читатель().
Ответ 8
вставка
print __doc__
сразу после объявления класса перед def __init__
будет печатать строку doc на консоли каждый раз, когда вы инициируете объект с классом