2013-01-06 16 views
5

simmilar pytanie (związane z python2: Python: check if method is static)Python3: sprawdzić, czy metoda jest statyczna

Pozwala concider następującą definicję klasy:

class A: 
    def f(self): 
    return 'this is f' 

    @staticmethod 
    def g(): 
    return 'this is g' 

W Pythonie 3 nie ma instancemethod już wszystko jest funkcją, więc odpowiedź związana z Pythonem 2 nie będzie już działać.

Jak już powiedziałem, wszystko działa, więc możemy zadzwonić pod numer A.f(0), ale oczywiście nie możemy zadzwonić pod numer A.f() (argument missmatch). Ale jeśli wykonamy instancję a=A() i wywołujemy a.f() Python przechodzi do funkcji A.f jako self jako pierwszego argumentu. Wywołanie a.g() uniemożliwia wysłanie lub przechwycenie self - więc musi istnieć sposób sprawdzenia, czy jest to metoda statyczna, czy nie.

Czy możemy sprawdzić w Pythonie3, czy metoda została zadeklarowana jako static czy nie?

+0

Czy mogę zapytać, dlaczego starasz się to zrobić? –

+1

oczywiście, robię własne ramy wtyczek i chcę sprawdzić niektóre deklaracje interfejsu i chciałbym wiedzieć, czy coś zostało zadeklarowane jako staticmethod lub nie :) –

Odpowiedz

8
class A: 
    def f(self): 
    return 'this is f' 

    @staticmethod 
    def g(): 
    return 'this is g' 
print(type(A.__dict__['g'])) 
print(type(A.g)) 

<class 'staticmethod'> 
<class 'function'> 
+0

świetnie! Czy mógłbyś wyjaśnić również dlaczego 'A .__ dict __ ['g']' daje coś innego niż 'A.g'? –

+5

'A .__ dict __ ['g']' różni się od 'A.g', ponieważ funkcje są [deskryptorami] (http://docs.python.org/2/reference/datamodel.html#descriptors). Obiekty funkcji są deskryptorami, ponieważ definiują metodę '__get__', która jest wywoływana przez magię, gdy dostęp do obiektu odbywa się za pomocą notacji kropkowej (np.' A.f'). Protokół deskryptorów określa, w jaki sposób (na przykład) funkcja _function_ zostaje przekształcona w metodę _bound po wywołaniu instancji. Przechodzenie przez '__dict__', zamiast używania notacji kropkowej, omija protokół deskryptora. –

1

Potrzebowałem tego rozwiązania i pisał na podstawie odpowiedzi z @root

def is_method_static(cls, method_name): 
    # http://stackoverflow.com/questions/14187973/python3-check-if-method-is-static 
    for c in cls.mro(): 
     if method_name in c.__dict__: 
      return isinstance(c.__dict__[method_name], staticmethod) 
    raise RuntimeError("Unable to find %s in %s" % (method_name, cls.__name__)) 
+0

To będzie działać tylko dla metod statycznych, które nie są dziedziczone. Możesz użyć 'inspect.getattr_static' zamiast bezpośredniego dostępu do' __dict__', jeśli chcesz wspierać odziedziczone statyczne metody. –

+0

Dzięki, getattr_static jest nowy w wersji 3.2. Mój kod działa zarówno w Python2, jak i Python3 –

Powiązane problemy