Muitos não estão cientes desse recurso, mas as funções (e métodos) do Python podem ter atributos . Ver:
>>> 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
Quais são os possíveis usos e abusos desse recurso no Python? Um bom uso que eu conheço é o uso da doutrina PLY para associar uma regra de sintaxe a um método. Mas e os atributos personalizados? Existem boas razões para usá-los?
python
function
attributes
Eli Bendersky
fonte
fonte
Respostas:
Normalmente, uso atributos de função como armazenamento para anotações. Suponha que eu queira escrever, no estilo de C # (indicando que um determinado método deve fazer parte da interface de serviço da web)
então eu posso definir
Em seguida, quando chega uma chamada de serviço da web, procuro o método, verifico se a função subjacente tem o atributo is_webmethod (o valor real é irrelevante) e recuso o serviço se o método estiver ausente ou não for chamado pela Web.
fonte
.__doc__
Eu os usei como variáveis estáticas para uma função. Por exemplo, dado o seguinte código C:
Eu posso implementar a função da mesma forma em Python:
Isso definitivamente se enquadra no "abuso" do fim do espectro.
fonte
Você pode fazer objetos da maneira JavaScript ... Não faz sentido, mas funciona;)
fonte
def test()
realmente necessário?Eu os uso com moderação, mas eles podem ser bastante convenientes:
Agora eu posso usar em
log
todo o meu módulo e redirecionar a saída simplesmente configurandolog.logfile
. Existem muitas outras maneiras de conseguir isso, mas essa é leve e simples. E embora tenha cheirado engraçado na primeira vez que fiz isso, acredito que cheira melhor do que ter umalogfile
variável global .fonte
Os atributos de função podem ser usados para gravar fechamentos leves que agrupam código e dados associados:
1.00934004784
2.00644397736
3.01593494415
fonte
time.sleep(1)
é melhor queos.system('sleep 1')
Eu criei este decorador auxiliar para definir facilmente os atributos das funções:
Um caso de uso é criar uma coleção de fábricas e consultar o tipo de dados que eles podem criar no nível meta de função.
Por exemplo (muito idiota):
fonte
factory1.datatype=list
logo abaixo da declaração como decoradores de estilo antigo?items()
vez deiteritems()
.Às vezes, uso um atributo de uma função para armazenar em cache valores já calculados. Você também pode ter um decorador genérico que generalize essa abordagem. Esteja ciente de problemas de simultaneidade e efeitos colaterais de tais funções!
fonte
Eu sempre assumi que a única razão pela qual isso era possível era que havia um lugar lógico para colocar uma sequência de documentos ou outras coisas desse tipo. Eu sei que se eu o usasse para qualquer código de produção, confundiria a maioria dos que o liam.
fonte