Tìm phương thức mà đối tượng Python có


426

Cho một đối tượng Python thuộc bất kỳ loại nào, có cách nào dễ dàng để có được danh sách tất cả các phương thức mà đối tượng này có không?

Hoặc là,

nếu điều này là không thể, thì có ít nhất một cách dễ dàng để kiểm tra xem nó có một phương thức cụ thể nào không ngoài việc kiểm tra xem có xảy ra lỗi khi phương thức đó được gọi không?


Câu trả lời:


521

Đối với nhiều đối tượng , bạn có thể sử dụng mã này, thay thế 'đối tượng' bằng đối tượng bạn quan tâm:

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

Tôi phát hiện ra nó tại diveintopython.net (Hiện đã được lưu trữ). Hy vọng rằng, sẽ cung cấp thêm một số chi tiết!

Nếu bạn nhận được một AttributeError, bạn có thể sử dụng này thay thế :

getattr(không dung nạp kiểu tiểu thư ảo trừu tượng python3.6. Mã này làm tương tự như trên và bỏ qua các ngoại lệ.

import pandas as pd 
df = pd.DataFrame([[10, 20, 30], [100, 200, 300]],  
                  columns=['foo', 'bar', 'baz']) 
def get_methods(object, spacing=20): 
  methodList = [] 
  for method_name in dir(object): 
    try: 
        if callable(getattr(object, method_name)): 
            methodList.append(str(method_name)) 
    except: 
        methodList.append(str(method_name)) 
  processFunc = (lambda s: ' '.join(s.split())) or (lambda s: s) 
  for method in methodList: 
    try: 
        print(str(method.ljust(spacing)) + ' ' + 
              processFunc(str(getattr(object, method).__doc__)[0:90])) 
    except: 
        print(method.ljust(spacing) + ' ' + ' getattr() failed') 


get_methods(df['foo']) 

3
Đó là một sự hiểu biết danh sách, trả về một danh sách các phương thức trong đó phương thức là một mục trong danh sách được trả về bởi dir (object) và trong đó mỗi phương thức được thêm vào danh sách chỉ khi getattr (object, method) trả về một cuộc gọi.
Mnebuerquo

1
Làm thế nào chính xác để bạn sử dụng này? Để nói in một danh sách các phương pháp.
đầm lầy

12
@marsh Để in các phương thức : print [method for method in dir(object) if callable(getattr(object, method))].
Orienteerix

1
Tôi nhận được một AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'khi tôi cố gắng để chạy này. Xem chi tiết tại stackoverflow.com/q/54713287/9677043 .
Karl Baker

1
không hoạt động cho đối tượng dataframe trong python 3.6.
Stefan Karlsson

226

Bạn có thể sử dụng hàm dựng sẵn dir()để lấy danh sách tất cả các thuộc tính mà mô-đun có. Hãy thử điều này tại dòng lệnh để xem nó hoạt động như thế nào.

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

Ngoài ra, bạn có thể sử dụng hasattr(module_name, "attr_name")hàm để tìm hiểu xem một mô-đun có thuộc tính cụ thể không.

Xem Hướng dẫn về hướng nội của Python để biết thêm thông tin.


hasattrđã giúp trường hợp sử dụng của tôi để tìm xem đối tượng python có biến thành viên hay phương thức cụ thể nào không.
Akshay

Tôi không chắc tại sao giải pháp này không được nâng cấp đủ. Đây là ngắn gọn và chính xác.
Prasad Raghavendra

93

Phương pháp đơn giản nhất là sử dụng dir(objectname). Nó sẽ hiển thị tất cả các phương thức có sẵn cho đối tượng đó. Thủ thuật hay.


2
Nó cũng hiển thị các thuộc tính của đối tượng, vì vậy nếu bạn muốn tìm phương thức cụ thể, nó sẽ không hoạt động.
eric

Đúng. Đã đồng ý. Nhưng, tôi không biết về bất kỳ kỹ thuật nào khác để chỉ lấy danh sách các phương thức. Có lẽ ý tưởng tốt nhất là lấy danh sách của cả hai thuộc tính và phương thức và sau đó sử dụng <hasattr (object, "method_name"> để lọc thêm?
Pawan Kumar

1
@neuronet, tôi đang cố chạy câu trả lời được chấp nhận nhưng nhận được AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'. Có ý kiến ​​gì không? Xem deets tại stackoverflow.com/q/54713287/9677043 . +1 cho @Pawan Kumar b / c câu trả lời hoạt động và @ljs cho lời hứa về một danh sách được lọc chỉ các phương thức.
Karl Baker

30

Để kiểm tra xem nó có một phương thức cụ thể không:

hasattr(object,"method")

14
Vì OP đang tìm kiếm một phương thức chứ không chỉ thuộc tính và thuộc tính, tôi nghĩ rằng bạn muốn tiến thêm một bước với:if hasattr(obj,method) and callable(getattr(obj,method)):
Bruno Bronosky

28

Tôi tin rằng những gì bạn muốn là một cái gì đó như thế này:

một danh sách các thuộc tính từ một đối tượng

Theo ý kiến ​​khiêm tốn của tôi, chức năng tích hợp dir()có thể thực hiện công việc này cho bạn. Lấy từ help(dir)đầu ra trên Python Shell của bạn:

thư mục (...)

dir([object]) -> list of strings

Nếu được gọi mà không có đối số, trả về tên trong phạm vi hiện tại.

Khác, trả về một danh sách được sắp xếp theo thứ tự các tên bao gồm (một số) các thuộc tính của đối tượng đã cho và các thuộc tính có thể truy cập từ nó.

Nếu đối tượng cung cấp một phương thức có tên __dir__, nó sẽ được sử dụng; mặt khác, logic dir () mặc định được sử dụng và trả về:

  • cho một đối tượng mô-đun: thuộc tính của mô-đun.
  • đối với một đối tượng lớp: các thuộc tính của nó và đệ quy các thuộc tính của các cơ sở của nó.
  • đối với bất kỳ đối tượng nào khác: thuộc tính của nó, thuộc tính của lớp và đệ quy các thuộc tính của lớp cơ sở của lớp.

Ví dụ:

$ 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']

Khi tôi đang kiểm tra vấn đề của bạn, tôi quyết định chứng minh sự suy nghĩ của mình, với định dạng đầu ra tốt hơn dir().

dir_attribut.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_attribut.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("")

Mong rằng tôi đã đóng góp :).


1
Đóng góp? Câu trả lời của bạn đã làm việc cho tôi trong Python 2.7.12, vậy quái nào!
gsamaras

23

Ngoài các câu trả lời trực tiếp hơn, tôi sẽ cảm thấy hối hận nếu tôi không đề cập đến iPython . Nhấn 'tab' để xem các phương thức khả dụng, với tự động hoàn thành.

Và một khi bạn đã tìm thấy một phương pháp, hãy thử:

help(object.method) 

để xem pydocs, chữ ký phương thức, v.v.

À ... REPL .


12

Nếu bạn đặc biệt muốn các phương thức , bạn nên sử dụng tests.ismethod .

Đối với tên phương thức:

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

Đối với các phương thức:

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

Đôi khi inspect.isroutinecũng có thể hữu ích (đối với phần mở rộng C, phần mở rộng C, Cython mà không có chỉ thị trình biên dịch "ràng buộc").


Bạn không nên sử dụng inspect.getmembersthay vì sử dụng dirtrong một sự hiểu biết danh sách?
Boris

Vâng, điều đó có vẻ tốt hơn!
paulmelnikow

11

Mở bash shell (ctrl + alt + T trên Ubuntu). Bắt đầu vỏ python3 trong đó. Tạo đối tượng để quan sát các phương thức của. Chỉ cần thêm một dấu chấm sau nó và nhấn hai lần "tab" và bạn sẽ thấy một cái gì đó như thế:

 user@note:~$ 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.
 >>> import readline
 >>> readline.parse_and_bind("tab: complete")
 >>> s = "Any object. Now it's a string"
 >>> s. # here tab should be pressed twice
 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(           

1
Trong khi chúng ta đang nói về cách giải quyết như thế này, tôi sẽ thêm rằng bạn cũng có thể chạy ipython, bắt đầu nhập đối tượng và nhấn tabvà nó cũng sẽ hoạt động. Không cần cài đặt đường dẫn
Max Coplan

1
@MaxCoplan Tôi đã thêm cách giải quyết trong mã cho các trường hợp không bật tính năng hoàn tất tab
Valery Ramusik

8

Vấn đề với tất cả các phương thức được chỉ ra ở đây là bạn KHÔNG thể chắc chắn rằng một phương thức không tồn tại.

Trong Python, bạn có thể chặn dấu chấm gọi qua __getattr____getattribute__ giúp tạo phương thức "lúc chạy"

Ví dụ:

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

Nếu bạn thực thi nó, bạn có thể gọi phương thức không tồn tại trong từ điển đối tượng ...

>>> 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

Và đó là lý do tại sao bạn sử dụng Dễ dàng hơn để yêu cầu sự tha thứ hơn là các mô hình cho phép trong Python.


6

Cách đơn giản nhất để có được danh sách các phương thức của bất kỳ đối tượng nào là sử dụng help()lệnh.

%help(object)

Nó sẽ liệt kê tất cả các phương thức có sẵn / quan trọng liên quan đến đối tượng đó.

Ví dụ:

help(str)

Làm gì %trong ví dụ đầu tiên? Nó không hoạt động trong Python 2.7 của tôi.
Scorchio

@Scorchio Tôi đã sử dụng "%" làm dấu nhắc thay vì ">>>" cho python. Bạn có thể loại bỏ% trước khi chạy lệnh.
Paritosh Vyas

3
import moduleName
for x in dir(moduleName):
print(x)

Điều này sẽ làm việc :)


1

Người ta có thể tạo một getAttrshàm sẽ trả về tên thuộc tính có thể gọi của đối tượng

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

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

Điều đó sẽ trở lại

['__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']

1

Không có cách nào đáng tin cậy để liệt kê tất cả các phương thức của đối tượng. dir(object)thường hữu ích, nhưng trong một số trường hợp, nó có thể không liệt kê tất cả các phương thức. Theo dir()tài liệu : "Với một đối số, cố gắng trả về danh sách các thuộc tính hợp lệ cho đối tượng đó."

Kiểm tra phương thức đó tồn tại có thể được thực hiện bằng callable(getattr(object, method))cách đã đề cập ở đó.


1

Lấy một danh sách làm đối tượng

obj = []

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

Bạn lấy:

['__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

... có ít nhất một cách dễ dàng để kiểm tra xem nó có một phương thức cụ thể nào không ngoài việc kiểm tra xem có xảy ra lỗi khi phương thức đó được gọi không

Mặc dù " Dễ xin tha thứ hơn là cho phép " chắc chắn là cách của Pythonic, nhưng điều bạn đang tìm kiếm có thể là:

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

0

Để tìm kiếm một phương thức cụ thể trong toàn bộ mô-đun

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

-1

Ví dụ, nếu bạn đang sử dụng shell plus, bạn có thể sử dụng cái này thay thế:

>> MyObject??

theo cách đó, với '??' ngay sau đối tượng của bạn, nó sẽ hiển thị cho bạn tất cả các thuộc tính / phương thức mà lớp có.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.