Niewielu jest świadomych tej funkcji, ale funkcje (i metody) Pythona mogą mieć atrybuty . Ujrzeć:
>>> 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
Jakie są możliwe zastosowania i nadużycia tej funkcji w Pythonie? Jednym z dobrych zastosowań, o których jestem świadomy, jest użycie przez PLY metody docstring do powiązania reguły składni z metodą. Ale co z niestandardowymi atrybutami? Czy istnieją dobre powody, aby z nich korzystać?
python
function
attributes
Eli Bendersky
źródło
źródło
Odpowiedzi:
Zazwyczaj używam atrybutów funkcji jako miejsca przechowywania adnotacji. Załóżmy, że chcę pisać, w stylu C # (wskazując, że pewna metoda powinna być częścią interfejsu usługi sieci Web)
wtedy mogę zdefiniować
Następnie, gdy nadejdzie wywołanie usługi internetowej, sprawdzam metodę, sprawdzam, czy podstawowa funkcja ma atrybut is_webmethod (rzeczywista wartość jest nieistotna), i odmawiam usługi, jeśli metoda jest nieobecna lub nie ma być wywoływana przez Internet.
źródło
.__doc__
Użyłem ich jako zmiennych statycznych dla funkcji. Na przykład biorąc pod uwagę następujący kod C:
Mogę podobnie zaimplementować tę funkcję w Pythonie:
Zdecydowanie wpadłoby to w „nadużycie” na końcu spektrum.
źródło
Możesz robić obiekty w JavaScript ... To nie ma sensu, ale działa;)
źródło
def test()
naprawdę konieczne?Używam ich oszczędnie, ale mogą być dość wygodne:
Teraz mogę używać w
log
całym module i przekierowywać dane wyjściowe po prostu przez ustawienielog.logfile
. Istnieje wiele innych sposobów na osiągnięcie tego, ale ten jest lekki i prosty. I chociaż pachniało śmiesznie za pierwszym razem, kiedy to robiłem, doszedłem do wniosku, że pachnie lepiej niż posiadanielogfile
zmiennej globalnej .źródło
Atrybutów funkcji można używać do pisania lekkich zamknięć, które zawijają kod i powiązane dane:
1,00934004784
2.00644397736
3.01593494415
źródło
time.sleep(1)
jest lepszy niżos.system('sleep 1')
Stworzyłem ten dekorator pomocnika, aby łatwo ustawić atrybuty funkcji:
Przykładem zastosowania jest utworzenie zbioru fabryk i przeszukanie typu danych, które można utworzyć na poziomie meta funkcji.
Na przykład (bardzo głupi):
źródło
factory1.datatype=list
tuż pod deklaracją, jak dekoratorzy w starym stylu?items()
zamiastiteritems()
.Czasami używam atrybutu funkcji do buforowania już obliczonych wartości. Możesz także mieć ogólny dekorator, który uogólnia to podejście. Uważaj na problemy z współbieżnością i skutki uboczne takich funkcji!
źródło
Zawsze zakładałem, że jedynym powodem, dla którego było to możliwe, było logiczne miejsce na umieszczenie dokumentu lub innych podobnych rzeczy. Wiem, że gdybym użył go w jakimkolwiek kodzie produkcyjnym, pomyliłby większość, którzy go czytają.
źródło