2008-08-29 16 views
233

podany obiekt Pythona jakiegokolwiek rodzaju, to istnieje prosty sposób uzyskać listę wszystkich metod, które ten obiekt ma?Znalezienie jakie metody obiektu Python

Albo

jeśli nie jest to możliwe, jest tam co najmniej łatwym sposobem sprawdzenia, czy posiada ono szczególny sposób inny niż po prostu sprawdzenie, czy wystąpi błąd, gdy wywoływana jest metoda?

+0

Stosowna: https://stackoverflow.com/q/46033277/1959808 –

Odpowiedz

297

Wydaje się, można użyć tego kodu, zastępując „obiektu” z przedmiotu, który Cię interesuje: -

[method_name for method_name in dir(object) 
if callable(getattr(object, method_name))] 

odkryłem go w this site, z nadzieją, że należy zapewnić pewne dalsze szczegóły!

+0

Nie jestem pewien, co staramy się osiągnąć tutaj, ale o „metoda” w tych 3 miejsc nie ma sensu do mnie . Zastąpienie "obiektu" przez "obiekt, który cię interesuje" zwróci wszystkie podpowiedzi dla dowolnego obiektu za pomocą pojedynczego wywoływacza. Proszę, pomóż mi zrozumieć punkt. –

+0

Może miałeś na myśli '[getattr (obj, method) dla metody w dir (obj), jeśli metoda == nazwa_metody i callable (getattr (obj, nazwa_metody))], która może być używana w następujący sposób: 'obj = {' foo ': 'bar'}; method_name = 'get'; x = [getattr (obj, method) dla metody w dir (obj), jeśli metoda == nazwa_metody i wywoływalna (getattr (obj, nazwa_metody)); '; a następnie 'if (len (x)): x [0] ('foo')' ... Wiem, że to jest naprawdę nieprzyjemne w jednym wierszu, ale komentarze nie zezwalają na podziały wierszy –

+0

@RichardBronosky, to może nie być Wasz sens, ale działa. – jwg

131

Można użyć wbudowanego w dir() funkcji, aby uzyskać listę wszystkich atrybutów moduł ma. Wypróbuj to w wierszu poleceń, aby zobaczyć, jak to działa.

>>> import moduleName 
>>> dir(moduleName) 

Ponadto, można użyć funkcji hasattr(module_name, "attr_name") aby dowiedzieć się, czy moduł ma specyficzny atrybut.

Zobacz Guide to Python introspection aby uzyskać więcej informacji.

+0

'hasattr' pomógł mi w użyciu, aby sprawdzić, czy obiekt Pythona ma określoną zmienną lub metodę. – Akshay

23

Aby sprawdzić, czy ma on szczególną metodę:

hasattr(object,"method") 
+11

ponieważ OP szuka metody, a nie tylko atrybutu, myślę, że chcesz pójść o krok dalej: 'if hasattr (obj, method) i callable (getattr (obj, method)):' –

17

Na szczycie bardziej bezpośrednich odpowiedzi, byłbym błędem gdybym nie wspomniał iPython. Naciśnij 'tab', aby zobaczyć dostępne metody, z autouzupełnianiem.

A kiedy już znaleźli sposób, spróbuj:

help(object.method) 

zobaczyć pydocs, podpis metody itd

Ahh ... REPL.

1

... jest tam co najmniej łatwym sposobem sprawdzenia, czy posiada ono szczególny sposób inny niż po prostu sprawdzenie, czy wystąpi błąd, gdy wywoływana jest metoda

Podczas „Easier to ask for forgiveness than permission” jest z pewnością Pythoniczny sposób, być może:

d={'foo':'bar', 'spam':'eggs'} 
if 'get' in dir(d): 
    d.get('foo') 
# OUT: 'bar' 
33

Najprostszą metodą jest użycie dir (objectname). Wyświetli wszystkie dostępne metody dla tego obiektu. Fajna sztuczka.

+0

Wyświetla również atrybuty obiektu, więc jeśli chcesz konkretnie znaleźć metody, nie zadziała. – neuronet

+0

Tak. Zgoda. Ale nie jestem świadomy żadnej innej techniki, aby uzyskać tylko listę metod.Może najlepszym pomysłem jest zdobycie listy zarówno atrybutów, jak i metod, a następnie użycie w celu dalszego odfiltrowania? –

+1

Zobacz zaakceptowaną odpowiedź – neuronet

5

Problem ze wszystkich metod wskazanych tutaj jest, że nie można mieć pewność, że metoda nie istnieje.

W Pythonie można przechwycić kropkę wzywającą thru __getattr__ i __getattribute__, dzięki czemu możliwe jest stworzenie metody „na starcie”

Exemple:

class MoreMethod(object): 
    def some_method(self, x): 
     return x 
    def __getattr__(self, *args): 
     return lambda x: x*2 

Jeśli go wykonać, można wywołać metodę non istniejące w słowniku obiektów ...

>>> o = MoreMethod() 
>>> o.some_method(5) 
5 
>>> dir(o) 
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'some_method'] 
>>> o.i_dont_care_of_the_name(5) 
10 

A to dlaczego używasz Easier to ask for forgiveness than permission paradygmaty w Pythonie.

7

Jeśli chcesz konkretnie metod, powinieneś użyć inspect.ismethod.

Dla nazw metoda:

import inspect 
method_names = [attr for attr in dir(self) if inspect.ismethod(getattr(self, attr))] 

Dla samych metod:

import inspect 
methods = [member for member in [getattr(self, attr) for attr in dir(self)] if inspect.ismethod(member)] 

Czasami inspect.isroutine mogą być przydatne także (dla wbudowanych wtyczek, rozszerzeń C Cython bez "wiązania" dyrektywy kompilatora).

+0

Odnośna odpowiedź: https://stackoverflow.com/a/1911287/1959808 –

2

Można utworzyć getAttrs funkcję, która zwraca obiekt za wywołalnych nazwy właściwości

def getAttrs(object): 
    return filter(lambda m: callable(getattr(object, m)), dir(object)) 

print getAttrs('Foo bar'.split(' ')) 

Że powrócić

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', 
'__delslice__', '__eq__', '__format__', '__ge__', '__getattribute__', 
'__getitem__', '__getslice__', '__gt__', '__iadd__', '__imul__', '__init__', 
'__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', 
'__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', 
'__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 
'remove', 'reverse', 'sort'] 
2

Nie ma niezawodny sposób wymienić wszystkich metod obiektu. dir(object) jest zwykle przydatny, ale w niektórych przypadkach może nie wyświetlać wszystkich metod. Zgodnie z dir() documentation: "Z argumentem, , należy spróbować uzyskać, aby zwrócić listę prawidłowych atrybutów dla tego obiektu."

Sprawdzanie, czy istnieje metoda, można wykonać pod numerem callable(getattr(object, method)), jak już wspomniano.

15

Wierzę, że to, co chcesz, jest coś takiego:

lista atrybutów z obiektu

Moim skromnym zdaniem, wbudowana funkcja dir() może zrobić to zadanie dla ty. Zrobione z help(dir) wyjściem na swojej Python Shell:

dir (...)

dir([object]) -> list of strings 

Jeśli wywołana bez argumentów, zwraca nazwy w bieżącym zakresie.

W przeciwnym razie zwracana jest alfabetyczna lista nazw zawierających (niektóre) atrybuty danego obiektu i dostępnych z niego atrybutów. Jeśli obiekt dostarcza metodę o nazwie __dir__, zostanie użyty; w przeciwnym razie używana jest domyślna logika dir() i zwraca:

  • dla obiektu modułu: atrybuty modułu.
  • dla obiektu klasy: jego atrybuty i rekurencyjnie atrybuty jego baz.
  • dla dowolnego innego obiektu: jego atrybuty, atrybuty danej klasy i rekursywnie atrybuty klas bazowych swojej klasy.

Na przykład:

$ python 
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 

>>> a = "I am a string" 
>>> 
>>> type(a) 
<class 'str'> 
>>> 
>>> dir(a) 
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', 
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', 
'__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', 
'__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', 
'__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', 
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', 
'_formatter_field_name_split', '_formatter_parser', 'capitalize', 
'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 
'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 
'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 
'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 
'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 
'translate', 'upper', 'zfill'] 

Jak sprawdzał swój problem, postanowiłem wykazać mój tok myślenia, z lepszym formatowania wyjścia dir().

dir_attributes.py (Python 2.7.6)

#!/usr/bin/python 
""" Demonstrates the usage of dir(), with better output. """ 

__author__ = "ivanleoncz" 

obj = "I am a string." 
count = 0 

print "\nObject Data: %s" % obj 
print "Object Type: %s\n" % type(obj) 

for method in dir(obj): 
    # the comma at the end of the print, makes it printing 
    # in the same line, 4 times (count) 
    print "| {0: <20}".format(method), 
    count += 1 
    if count == 4: 
     count = 0 
     print 

dir_attributes.py (Python 3.4.3)

#!/usr/bin/python3 
""" Demonstrates the usage of dir(), with better output. """ 

__author__ = "ivanleoncz" 

obj = "I am a string." 
count = 0 

print("\nObject Data: ", obj) 
print("Object Type: ", type(obj),"\n") 

for method in dir(obj): 
    # the end=" " at the end of the print statement, 
    # makes it printing in the same line, 4 times (count) 
    print("| {:20}".format(method), end=" ") 
    count += 1 
    if count == 4: 
     count = 0 
     print("") 

nadzieję, że przyczyniły się :).

2

Otwórz powłokę bash (ctrl + alt + T na Ubuntu). Uruchom w nim powłokę python3. Utwórz obiekt do obserwacji metod. Wystarczy dodać kropkę po nim i naciśnij dwa razy "Tab", a zobaczysz coś takiego:

[email protected]:~$ python3 
Python 3.4.3 (default, Nov 17 2016, 01:08:31) 
[GCC 4.8.4] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
>>> s = "Any object. Now it's a string" 
>>> s. # here tab should be pressed twice times 
s.__add__(   s.__rmod__(   s.istitle(
s.__class__(  s.__rmul__(   s.isupper(
s.__contains__(  s.__setattr__(  s.join(
s.__delattr__(  s.__sizeof__(  s.ljust(
s.__dir__(   s.__str__(   s.lower(
s.__doc__   s.__subclasshook__( s.lstrip(
s.__eq__(   s.capitalize(  s.maketrans(
s.__format__(  s.casefold(   s.partition(
s.__ge__(   s.center(   s.replace(
s.__getattribute__( s.count(   s.rfind(
s.__getitem__(  s.encode(   s.rindex(
s.__getnewargs__( s.endswith(   s.rjust(
s.__gt__(   s.expandtabs(  s.rpartition(
s.__hash__(   s.find(    s.rsplit(
s.__init__(   s.format(   s.rstrip(
s.__iter__(   s.format_map(  s.split(
s.__le__(   s.index(   s.splitlines(
s.__len__(   s.isalnum(   s.startswith(
s.__lt__(   s.isalpha(   s.strip(
s.__mod__(   s.isdecimal(  s.swapcase(
s.__mul__(   s.isdigit(   s.title(
s.__ne__(   s.isidentifier(  s.translate(
s.__new__(   s.islower(   s.upper(
s.__reduce__(  s.isnumeric(  s.zfill(
s.__reduce_ex__( s.isprintable(  
s.__repr__(   s.isspace(   
0

Zrób listę jako obiekt

obj = [] 

list(filter(lambda x:callable(getattr(obj,x)),obj.__dir__()))

otrzymasz:

['__add__', 
'__class__', 
'__contains__', 
'__delattr__', 
'__delitem__', 
'__dir__', 
'__eq__', 
'__format__', 
'__ge__', 
'__getattribute__', 
'__getitem__', 
'__gt__', 
'__iadd__', 
'__imul__', 
'__init__', 
'__init_subclass__', 
'__iter__', 
'__le__', 
'__len__', 
'__lt__', 
'__mul__', 
'__ne__', 
'__new__', 
'__reduce__', 
'__reduce_ex__', 
'__repr__', 
'__reversed__', 
'__rmul__', 
'__setattr__', 
'__setitem__', 
'__sizeof__', 
'__str__', 
'__subclasshook__', 
'append', 
'clear', 
'copy', 
'count', 
'extend', 
'index', 
'insert', 
'pop', 
'remove', 
'reverse', 
'sort'] 
0

Aby wyszukać konkretną metodę w całym module

for method in dir(module) : 
    if "keyword_of_methode" in method : 
    print(method, end="\n") 
Powiązane problemy