Не многие знают об этой функции, но функции (и методы) Python могут иметь атрибуты . Вот:
>>> def foo(x):
... pass
...
>>> foo.score = 10
>>> dir(foo)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name', 'score']
>>> foo.score
10
>>> foo.score += 1
>>> foo.score
11
Каковы возможные варианты использования и злоупотребления этой функцией в Python? Одно хорошее использование, которое я знаю, это использование PLY строки документации для связи правила синтаксиса с методом. Но как насчет пользовательских атрибутов? Есть ли веские причины для их использования?
python
function
attributes
Эли Бендерский
источник
источник
Ответы:
Я обычно использую атрибуты функции в качестве хранилища для аннотаций. Предположим, я хочу написать в стиле C # (указывая, что определенный метод должен быть частью интерфейса веб-службы)
тогда я могу определить
Затем, когда поступает вызов веб-службы, я просматриваю метод, проверяю, имеет ли базовая функция атрибут is_webmethod (фактическое значение не имеет значения), и отказываюсь от службы, если метод отсутствует или не предназначен для вызова через Интернет.
источник
.__doc__
Я использовал их в качестве статических переменных для функции. Например, учитывая следующий код C:
Я могу реализовать функцию аналогично в Python:
Это определенно попадет в конец «злоупотреблений» спектра.
источник
Вы можете делать объекты способом JavaScript ... Это не имеет смысла, но это работает;)
источник
def test()
действительно необходимо?Я использую их экономно, но они могут быть довольно удобными:
Теперь я могу использовать
log
весь модуль и перенаправлять вывод, просто установивlog.logfile
. Есть много и много других способов сделать это, но этот легкий и грязный. И хотя в первый раз, когда я это сделал, пахло забавно, я пришел к выводу, что пахнет лучше, чем наличие глобальнойlogfile
переменной.источник
Атрибуты функций могут использоваться для записи облегченных замыканий, которые обертывают код и связанные данные вместе:
+1,00934004784
+2,00644397736
+3,01593494415
источник
time.sleep(1)
лучше чемos.system('sleep 1')
Я создал этот вспомогательный декоратор для легкой установки атрибутов функции:
Вариант использования - создать коллекцию фабрик и запросить тип данных, который они могут создать на мета-уровне функции.
Например (очень тупой):
источник
factory1.datatype=list
прямо под объявлением, как декораторы старого стиля?items()
вместоiteritems()
.Иногда я использую атрибут функции для кэширования уже вычисленных значений. Вы также можете иметь универсальный декоратор, который обобщает этот подход. Помните о проблемах параллелизма и побочных эффектах таких функций!
источник
Я всегда полагал, что единственная причина, по которой это было возможно, заключалась в том, что было логичное место для размещения строки документации или другого подобного материала. Я знаю, если бы я использовал его для какого-либо производственного кода, это бы сбило с толку большинство, кто его читает.
источник