пользовательский оператор печати для объектов функций Python - PullRequest
2 голосов
/ 08 декабря 2010

Я знаю, что если я напишу класс, я могу определить пользовательскую функцию печати, как показано ниже.

>>> class F:
...     def __str__(self):
...             return 'This describes the data of F.'
... 
>>> f = F()
>>> print f
This describes the data of F.

Но что, если я хочу сделать то же самое для функционального объекта? Например,

>>> def f():
...     pass
... 
>>> g = f
>>> print g
<function f at 0x7f738d6da5f0>

Вместо '' я бы хотел как-то указать, что было напечатано. Мотивация для этого заключается в том, что я собираюсь сохранить несколько объектов-функций в списке, и я бы хотел перебрать список и вывести понятные человеку описания типов функций без дополнительной сложности, например: кортежи функциональных объектов и строк.

Заранее благодарим за любую помощь, которую вы можете предоставить.

Редактировать: Я изменил свой пример, чтобы отразить то, что я пытался передать, к сожалению, я набрал 'f ()', когда имел в виду 'f'. Меня интересует настраиваемая метка для объекта функции, а не настройка возврата (что очевидно, как это сделать). Извините за путаницу, это вызвало.

Ответы [ 5 ]

4 голосов
/ 08 декабря 2010

Другие предложили строки документа, но строка документа, вероятно, должна более подробно описывать, что делает функция. Если вам нужен короткий атрибут, описывающий функцию, один из вариантов ниже может быть тем, что вы ищете:

Вариант 1

Вы говорите, что хотите изменить описание объекта по умолчанию?

>>> def f1(): pass
...
>>> def f2(): pass
...
>>> L = [f1,f2]
>>> print L
[<function f1 at 0x00AA72F0>, <function f2 at 0x00AA73B0>]

Если вы хотите настроить описание функций в списке выше, используйте decorator . Декоратор ниже оборачивает каждую функцию, декорированную в объект, который действует как исходная функция, но имеет собственное представление:

def doc(s):
    class __doc(object):
        def __init__(self,f):
            self.func = f
            self.desc = s
        def __call__(self,*args,**kwargs):
            return self.func(*args,**kwargs)
        def __repr__(self):
            return '<function {0} "{1}">'.format(self.func.func_name,self.desc)
    return __doc

@doc('a+b')
def sum(a,b):
    return a + b

@doc('a-b')
def diff(a,b):
    return a - b

L = [sum,diff]
print L
for f in L:
    print f(5,3)

выход

[<function sum "a+b">, <function diff "a-b">]
8
2

Вариант 2

Кроме того, вы можете хранить атрибуты в своих функциях и отображать их по мере необходимости:

def sum(a,b):
    return a + b
sum.desc = 'a+b'

def diff(a,b):
    return a-b
diff.desc = 'a-b'

L = [sum,diff]
for f in L:
    print f.desc,f(8,3)

выход

a+b 11
a-b 5

Вариант 3

Вы также можете сделать вариант 2 с декоратором:

def doc(s):
    def __doc(f):
        f.desc = s
        return f
    return __doc

@doc('a+b')
def sum2(a,b):
    return a + b

@doc('a-b')
def diff2(a,b):
    return a - b

L = [sum2,diff2]
for f in L:
    print f.desc,f(8,3)

выход

a+b 11
a-b 5
3 голосов
/ 08 декабря 2010

Несколько ошибок:

>>> def f():
...     pass
... 
>>> g = f()     <---- g is the return value of running f
>>> print g
None

В первом случае, когда вы вызываете print, вы вызываете строковое представление f

>>> f = F()
>>> print f    <----- f is an instance of class F and 
               <----- print f tries to provide a suitable string representation
               <----- by calling f.__str__

Вы должны использовать строки документадля ваших мотивов

>>> def f():
...     " some doc"
...     pass
... 
>>> 
>>> f.__doc__
' some doc'
>>> 

То, что вы пытаетесь сделать, это переопределить обертку метода __str__.

>>> def f():
...     "some documentation .."
...     pass
... 
>>> 
>>> f.__str__
<method-wrapper '__str__' of function object at 0x100430140>
>>> 
2 голосов
/ 08 декабря 2010

Вы не можете изменить то, что происходит при печати функции, но вы можете заставить класс вести себя как функция:

class f(object):
    def __str__(self):
        return "I'm a function!"

    def __call__(self):
        print "who called?"


print f # I'm a function!
f() # who called?
0 голосов
/ 08 декабря 2010
>>> g = f # no ()! That *calls* the function.
>>> print g
<function f at 0x########>
0 голосов
/ 08 декабря 2010

Функции возвращают значения. Значение, присвоенное переменной g, будет напечатано. Если вы хотите что-то напечатать, просто убедитесь, что функция f возвращает строку.

>>> def f():
...     return "Print me"
... 
>>> g = f()
>>> print g
Print me
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...