การค้นหาวิธีการที่วัตถุ Python มี


428

รับวัตถุหลามชนิดใดมีวิธีง่าย ๆ เพื่อรับรายการของวิธีการทั้งหมดที่วัตถุนี้มี?

หรือ,

หากไม่สามารถทำได้มีอย่างน้อยวิธีง่าย ๆ ในการตรวจสอบว่ามีวิธีการเฉพาะนอกเหนือจากเพียงตรวจสอบว่ามีข้อผิดพลาดเกิดขึ้นเมื่อวิธีการที่เรียกว่า?


ที่เกี่ยวข้อง: stackoverflow.com/q/46033277/1959808
Ioannis Filippidis

คำตอบ:


523

สำหรับวัตถุจำนวนมากคุณสามารถใช้รหัสนี้แทนที่ 'วัตถุ' ด้วยวัตถุที่คุณสนใจ:

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

ฉันค้นพบมันที่diveintopython.net (ตอนนี้ถูกเก็บถาวร) หวังว่าจะให้รายละเอียดเพิ่มเติม!

หากคุณได้รับAttributeErrorคุณสามารถใช้สิ่งนี้แทน :

getattr(เป็นโมฆะของ pandas style python3.6 class sub-class เสมือนนามธรรม รหัสนี้ทำเช่นเดียวกับข้างบนและละเว้นข้อยกเว้น

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
มันเป็นความเข้าใจในรายการคืนรายการของวิธีการที่ method เป็นรายการในรายการที่ส่งคืนโดย dir (วัตถุ) และที่แต่ละวิธีจะถูกเพิ่มลงในรายการก็ต่อเมื่อ getattr (object, method) ส่งคืน callable
Mnebuerquo

1
คุณใช้สิ่งนี้ได้อย่างไร หากต้องการพิมพ์รายการวิธีการ
Marsh

12
@marsh หากต้องการพิมพ์วิธีการ: print [method for method in dir(object) if callable(getattr(object, method))].
Orienteerix

1
ฉันได้รับAttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'เมื่อฉันพยายามเรียกใช้ ดูรายละเอียดได้ที่stackoverflow.com/q/54713287/9677043
Karl Baker

1
ไม่สามารถใช้งานได้กับออบเจ็กต์ pandas dataframe ใน python 3.6
Stefan Karlsson

226

คุณสามารถใช้dir()ฟังก์ชันในตัวเพื่อรับรายการคุณลักษณะทั้งหมดที่โมดูลมี ลองทำสิ่งนี้ที่บรรทัดคำสั่งเพื่อดูว่ามันทำงานอย่างไร

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

นอกจากนี้คุณสามารถใช้hasattr(module_name, "attr_name")ฟังก์ชั่นเพื่อค้นหาว่าโมดูลมีคุณสมบัติเฉพาะ

ดูคู่มือการวิปัสสนาหลามของ Pythonสำหรับข้อมูลเพิ่มเติม


hasattrช่วยกรณีใช้ของฉันเพื่อค้นหาว่าวัตถุหลามมีตัวแปรสมาชิกหรือวิธีการเฉพาะ
Akshay

ฉันไม่แน่ใจว่าทำไมการแก้ปัญหานี้จึงไม่เพียงพอ นี่คือคำย่อและถูกต้อง
Prasad Raghavendra

93

dir(objectname)วิธีที่ง่ายที่สุดคือการใช้งาน มันจะแสดงวิธีการทั้งหมดที่มีให้สำหรับวัตถุนั้น เคล็ดลับเด็ด ๆ


2
นอกจากนี้ยังแสดงคุณลักษณะของวัตถุด้วยดังนั้นหากคุณต้องการค้นหาวิธีการโดยเฉพาะมันจะไม่ทำงาน
eric

ใช่. ตกลง แต่ฉันไม่ได้ตระหนักถึงเทคนิคอื่นใดที่จะได้รับรายการวิธีการเท่านั้น อาจเป็นความคิดที่ดีที่สุดที่จะได้รับรายชื่อทั้งคุณสมบัติและวิธีการและจากนั้นใช้ <hasattr (object, "method_name"> เพื่อกรองเพิ่มเติมหรือไม่
Pawan Kumar

1
@neuronet ฉันพยายามที่จะใช้คำตอบที่ได้รับการยอมรับ AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'แต่ได้รับ ความคิดใด ๆ ดู deets ที่ stackoverflow.com/q/54713287/9677043 +1 ถึง @Pawan Kumar b / c คำตอบใช้ได้ผลและ @ljs สำหรับคำสัญญาของรายการวิธีการกรองที่ถูกกรอง
Karl Baker

30

วิธีตรวจสอบว่ามีวิธีการเฉพาะหรือไม่:

hasattr(object,"method")

14
ตั้งแต่ OP กำลังมองหาวิธีการและไม่เพียง แต่และคุณลักษณะฉันคิดว่าคุณต้องการไปอีกขั้นด้วย:if hasattr(obj,method) and callable(getattr(obj,method)):
Bruno Bronosky

28

ฉันเชื่อว่าสิ่งที่คุณต้องการคืออะไรเช่นนี้:

รายการของคุณลักษณะจากวัตถุ

ในความเห็นต่ำต้อยของฉันฟังก์ชั่นในตัวdir()สามารถทำงานนี้ให้คุณได้ นำมาจากhelp(dir)ผลลัพธ์บน Python Shell ของคุณ:

dir ( ... )

dir([object]) -> list of strings

หากถูกเรียกโดยไม่มีอาร์กิวเมนต์ให้ส่งคืนชื่อในขอบเขตปัจจุบัน

มิฉะนั้นส่งคืนรายชื่ออักษรที่ประกอบด้วยตัวอักษร (บางส่วน) ของแอตทริบิวต์ของวัตถุที่กำหนดและของคุณลักษณะที่เข้าถึงได้จากมัน

หากวัตถุระบุวิธีการตั้งชื่อวัตถุ__dir__นั้นจะถูกนำมาใช้; มิฉะนั้นจะใช้ตรรกะ dir () เริ่มต้นและส่งคืน:

  • สำหรับวัตถุโมดูล: แอตทริบิวต์ของโมดูล
  • สำหรับคลาสอ็อบเจ็กต์: แอ็ตทริบิวต์และแอ็ตทริบิวต์ฐานของมันแบบวนซ้ำ
  • สำหรับวัตถุอื่น ๆ : คุณลักษณะของมันแอตทริบิวต์ของคลาสและเรียกใช้คุณสมบัติของคลาสพื้นฐานของคลาสนั้นซ้ำ

ตัวอย่างเช่น:

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

ขณะที่ฉันกำลังตรวจสอบปัญหาของคุณฉันตัดสินใจที่จะสาธิตขบวนการคิดด้วยการจัดรูปแบบผลลัพธ์ที่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("")

หวังว่าฉันจะช่วย :)


1
มีส่วนร่วม? คำตอบของคุณใช้ได้สำหรับฉันใน Python 2.7.12 ดังนั้นใช่แล้ว!
gsamaras

23

ด้านบนของคำตอบที่ตรงมากขึ้นฉันจะสะเพร่าถ้าผมไม่ได้พูดถึงIPython กด 'แท็บ' เพื่อดูวิธีการที่ใช้ได้พร้อมการเติมข้อความอัตโนมัติ

และเมื่อคุณพบวิธีการแล้วให้ลอง:

help(object.method) 

เพื่อดู pydocs ลายเซ็นวิธีการ ฯลฯ

อ่า ... REPL


12

หากคุณต้องการวิธีการเฉพาะคุณควรใช้inspect.ismethod inspect.ismethod

สำหรับชื่อวิธีการ:

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

สำหรับวิธีการเอง:

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

บางครั้งinspect.isroutineก็มีประโยชน์เช่นกัน (สำหรับบิวด์อิน, ส่วนขยาย C, Cython โดยไม่มีคำสั่งคอมไพเลอร์ "รวม")


คุณไม่ควรใช้inspect.getmembersแทนการใช้dirในรายการความเข้าใจใช่หรือไม่
บอริส

ใช่มันดูดีขึ้น!
paulmelnikow

11

เปิด bash shell (ctrl + alt + T บน Ubuntu) เริ่ม python3 ในนั้น สร้างวัตถุเพื่อสังเกตวิธีการ เพียงเพิ่มจุดหลังจากนั้นกดสองครั้ง "แท็บ" และคุณจะเห็นสิ่งที่:

 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
ขณะที่เรากำลังพูดถึงวิธีแก้ปัญหาเช่นนี้ฉันจะเพิ่มว่าคุณยังสามารถเรียกใช้ipythonเริ่มพิมพ์วัตถุและกดtabและมันจะทำงานได้ดี ไม่จำเป็นต้องตั้งค่า readline
Max Coplan

1
@MaxCoplan ฉันได้เพิ่มวิธีแก้ปัญหาในรหัสสำหรับกรณีที่ไม่ได้เปิดใช้งานการกรอกข้อมูลแท็บตามค่าเริ่มต้น
Valery Ramusik

8

ปัญหาของวิธีการทั้งหมดที่ระบุในที่นี้คือคุณไม่สามารถมั่นใจได้ว่าไม่มีวิธีการ

ใน Python คุณสามารถตัดทอนการเรียกจุดผ่าน__getattr__และ__getattribute__ทำให้สามารถสร้างเมธอด "at runtime"

กันตัวอย่าง:

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

หากคุณดำเนินการคุณสามารถเรียกใช้เมธอดที่ไม่มีอยู่ในพจนานุกรมวัตถุ ...

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

และนี่คือเหตุผลที่คุณใช้วิธีที่ง่ายกว่าเพื่อขอการให้อภัยมากกว่ากระบวนทัศน์การอนุญาตใน Python


6

วิธีที่ง่ายที่สุดในการรับรายการเมธอดของวัตถุใด ๆ คือการใช้help()คำสั่ง

%help(object)

มันจะแสดงรายการวิธีการที่มีอยู่ / สำคัญทั้งหมดที่เกี่ยวข้องกับวัตถุนั้น

ตัวอย่างเช่น:

help(str)

อะไร%ทำในตัวอย่างแรก? มันไม่ทำงานใน Python 2.7 ของฉัน
Scorchio

@Scorchio ฉันได้ใช้ "%" เป็นพรอมต์แทน ">>>" สำหรับ python คุณสามารถถอด% ออกก่อนที่จะรันคำสั่ง
Paritosh Vyas


1

หนึ่งสามารถสร้างgetAttrsฟังก์ชั่นที่จะส่งกลับชื่อคุณสมบัติที่เรียกได้ของวัตถุ

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

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

ว่าจะกลับมา

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

ไม่มีวิธีที่เชื่อถือได้ในการแสดงรายการวิธีการของวัตถุทั้งหมด dir(object)มักจะมีประโยชน์ แต่ในบางกรณีอาจไม่แสดงรายการวิธีการทั้งหมด อ้างอิงจากdir()เอกสาร : "ด้วยการโต้แย้งพยายามส่งคืนรายการแอตทริบิวต์ที่ถูกต้องสำหรับวัตถุนั้น"

การตรวจสอบวิธีการที่มีอยู่นั้นสามารถทำได้โดยวิธีcallable(getattr(object, method))ดังกล่าวแล้ว


1

ใช้รายการเป็นวัตถุ

obj = []

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

คุณได้รับ:

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

... มีวิธีที่ง่ายอย่างน้อยในการตรวจสอบว่ามีวิธีการเฉพาะนอกเหนือจากการตรวจสอบว่ามีข้อผิดพลาดเกิดขึ้นหรือไม่เมื่อมีการเรียกใช้เมธอด

ในขณะที่ " ง่ายกว่าที่จะขอการให้อภัยมากกว่าการอนุญาต " เป็นวิธี Pythonic อย่างแน่นอนสิ่งที่คุณกำลังมองหาอาจจะ:

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

0

เพื่อที่จะค้นหาวิธีการเฉพาะในโมดูลทั้งหมด

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

-1

ตัวอย่างเช่นถ้าคุณใช้ shell plus คุณสามารถใช้สิ่งนี้แทน:

>> MyObject??

ด้วยวิธีนั้นด้วย '??' หลังจากวัตถุของคุณมันจะแสดงคุณสมบัติ / วิธีการเรียนทั้งหมด

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.