मैं पायथन वर्ग में विधियों की सूची कैसे प्राप्त करूं?


329

1
स्रोत ..... स्रोत ...
RickyA

4
@JonCrowell यह नहीं है कि बल कैसे काम करता है।
केन विलियम्स

संकलनकर्ता निर्देश bindingकार्यों का उपयोग करने वाले
साइथन के लिए

4
Python3 पर: [f for f in dir(ClassName) if not f.startswith('_')]या बस dir(ClassName)सब कुछ के लिए
Seraf

@ शेरा कृपया टिप्पणियों में उत्तर पोस्ट न करें। इसके बजाय एक उत्तर पोस्ट करें।
वेजेंड्रिया

जवाबों:


331

एक उदाहरण ( optparse.OptionParserवर्ग के तरीकों की सूची ):

>>> from optparse import OptionParser
>>> import inspect
#python2
>>> inspect.getmembers(OptionParser, predicate=inspect.ismethod)
[([('__init__', <unbound method OptionParser.__init__>),
...
 ('add_option', <unbound method OptionParser.add_option>),
 ('add_option_group', <unbound method OptionParser.add_option_group>),
 ('add_options', <unbound method OptionParser.add_options>),
 ('check_values', <unbound method OptionParser.check_values>),
 ('destroy', <unbound method OptionParser.destroy>),
 ('disable_interspersed_args',
  <unbound method OptionParser.disable_interspersed_args>),
 ('enable_interspersed_args',
  <unbound method OptionParser.enable_interspersed_args>),
 ('error', <unbound method OptionParser.error>),
 ('exit', <unbound method OptionParser.exit>),
 ('expand_prog_name', <unbound method OptionParser.expand_prog_name>),
 ...
 ]
# python3
>>> inspect.getmembers(OptionParser, predicate=inspect.isfunction)
...

ध्यान दें कि getmembers2-ट्यूपल्स की सूची लौटाता है। पहला आइटम सदस्य का नाम है, दूसरा आइटम मूल्य है।

आप इसके लिए एक उदाहरण भी दे सकते हैं getmembers:

>>> parser = OptionParser()
>>> inspect.getmembers(parser, predicate=inspect.ismethod)
...

4
सही, विधेय हिस्सा महत्वपूर्ण है, अन्यथा आपको अतिरिक्त मेटा जानकारी के साथ वही चीज़ मिलती है जो तानाशाही है । धन्यवाद।
प्यूरेल

2
क्या यह कक्षा में सभी तरीकों की सूची तैयार करेगा (जिनमें अन्य वर्ग से विरासत में मिला है), या क्या यह केवल उन तरीकों की सूची देगा जो स्पष्ट रूप से उस कक्षा में परिभाषित हैं?
एंडरसन ग्रीन

10
inspect.isroutineअधिक उपयुक्त विधेय हो सकता है; inspect.ismethodसभी वस्तुओं के तरीकों के लिए काम नहीं करता है।
गैविन एस। यानसी

1
यह केवल कक्षा के उदाहरण का उपयोग करते समय काम करता है (उदाहरण के रूप में अच्छी तरह से करता है)। क्या यह अपेक्षित व्यवहार है?
क्रिश्चियन रियलल-फ्लुर्टी

2
अजगर 3.7 पर कम से कम यह काम नहीं करता है, आपको क्लास को तुरंत करना होगा
kederrac

222

नहीं है dir(theobject)सूची सभी क्षेत्रों और अपने वस्तु के तरीकों (एक टपल के रूप में) करने के लिए विधि और मॉड्यूल का निरीक्षण (codeape लिखने के रूप में) ( "में" ") क्षेत्रों और उनके डॉक के साथ तरीकों सूची।

क्योंकि पायथन में सब कुछ (यहां तक ​​कि फ़ील्ड) कहा जा सकता है, मुझे यकीन नहीं है कि केवल तरीकों को सूचीबद्ध करने के लिए एक अंतर्निहित फ़ंक्शन है। अगर आप का प्रयास करना चाहें वस्तु आप के माध्यम से प्राप्त dirहै प्रतिदेय या नहीं।


3
dir (ऑब्जेक्ट) सबसे सरल समाधान है जिसका मैंने उपयोग किया है।
lstodd

@skjerns इसे टाइप करने के लिए 5 प्रतीक लगते हैं। :)
Dr_Zaszuś

117

बाहरी पुस्तकालयों के बिना पायथन 3.x उत्तर

method_list = [func for func in dir(Foo) if callable(getattr(Foo, func))]

डंडर-बहिष्कृत परिणाम:

method_list = [func for func in dir(Foo) if callable(getattr(Foo, func)) and not func.startswith("__")]

38

मान लें कि आप सूची वर्ग से जुड़े सभी तरीकों को जानना चाहते हैं बस निम्न प्रकार लिखें

 print (dir(list))

ऊपर आपको सूची वर्ग के सभी तरीके बताएंगे


2
यह एक सबसे अच्छा समाधान है
जीशान अहमद

3
print([ m for m in dir(my_class) if not m.startswith('__')])
इव्ज

32

संपत्ति की कोशिश करो __dict__


16
मुझे लगता है कि आपका मतलब तानाशाही है । लेकिन यह उदाहरण की विशेषताओं को सूचीबद्ध करता है, विधियों को नहीं।
me_and

1
... जो मेरे लिए भी काम नहीं किया। मार्कडाउन सिंटैक्स से परामर्श करने के बाद, मुझे लगता है कि मेरा मतलब __dict__ है।
मेरे_और

3
@me_and आप शायद "self .__ dict__" कर रहे हैं या, अधिक उदारता से, उदाहरण के संस्करण को बुला रहे हैं __dict__। हालाँकि, कक्षाओं में __dict__भी एक है और उस वर्ग के तरीकों को प्रदर्शित करना चाहिए :)
सीउक्स

21

आप फ़ंक्शनटाइप को भी प्रकारों से आयात कर सकते हैं और इसके साथ परीक्षण कर सकते हैं class.__dict__:

from types import FunctionType

class Foo:
    def bar(self): pass
    def baz(self): pass

def methods(cls):
    return [x for x, y in cls.__dict__.items() if type(y) == FunctionType]

methods(Foo)  # ['bar', 'baz']

इसने मेरे लिए अच्छा काम किया। मैंने and not x.startswith('_')सूची के अंत में अपने उपयोग __init__और निजी तरीकों को अनदेखा करने के लिए समझ के लिए जोड़ दिया ।
क्रिस्टोफर पियर्सन

2
आप से छुटकारा पा सकते importकी FunctionTypeके साथ एक throwaway लैम्ब्डा का उपयोग करके type():type(lambda:0)
Tersosauros

isinstancetype(y) == FunctionTypeयहां से बेहतर होगा ।
ग्लोवेनी

13

ध्यान दें कि आपको यह विचार करने की आवश्यकता है कि क्या आप आधार वर्गों से वे तरीके चाहते हैं जो कि विरासत में मिले (लेकिन अतिप्राप्त नहीं) परिणाम में शामिल हैं। dir()और inspect.getmembers()संचालन आधार वर्ग तरीकों में शामिल करते हैं, लेकिन के उपयोग __dict__विशेषता नहीं है।


3

यह भी काम करता है:

mymodule.py

def foo(x)
   return 'foo'
def bar()
   return 'bar'

दूसरी फाइल में

import inspect
import mymodule
method_list = [ func[0] for func in inspect.getmembers(mymodule, predicate=inspect.isroutine) if callable(getattr(mymodule, func[0])) ]

उत्पादन:

['foo', 'bar']

अजगर डॉक्स से:

inspect.isroutine (वस्तु)

Return true if the object is a user-defined or built-in function or method.

2
def find_defining_class(obj, meth_name):
    for ty in type(obj).mro():
        if meth_name in ty.__dict__:
            return ty

इसलिए

print find_defining_class(car, 'speedometer') 

पायथन पेज 210 सोचें


3
5 का इंडेंटेशन? कीवर्ड को बड़ा करना? गैर pep8 शैली रिक्ति?
फ्लोरी डे

1
एक बार कोडिंग कन्वेंशन नाज़ियों को नहीं मिला!
rbennell

1
यह प्रश्न का उत्तर कैसे देता है?
अरन-फे

2

इस दृष्टिकोण है:

[getattr(obj, m) for m in dir(obj) if not m.startswith('__')]

वर्ग उदाहरण के साथ काम करते समय , शायद सिर्फ नाम के बजाय विधि संदर्भों के साथ एक सूची वापस करना बेहतर होगा। यदि वह आपका लक्ष्य है, साथ ही साथ

  1. का उपयोग करते हुए import
  2. __init__सूची से निजी तरीकों (जैसे ) को छोड़कर

यह उपयोग का हो सकता है। संक्षेप में, एक वर्ग की तरह

class Ghost:
    def boo(self, who):
        return f'Who you gonna call? {who}'

हम उदाहरण के साथ पुनर्प्राप्ति की जाँच कर सकते हैं

>>> g = Ghost()
>>> methods = [getattr(g, m) for m in dir(g) if not m.startswith('__')]
>>> print(methods)
[<bound method Ghost.boo of <__main__.Ghost object at ...>>]

तो आप इसे तुरंत कॉल कर सकते हैं:

>>> for method in methods:
...     print(method('GHOSTBUSTERS'))
...
Who you gonna call? GHOSTBUSTERS

Use एक उपयोग मामला:

मैंने इसका इस्तेमाल यूनिट टेस्टिंग के लिए किया । एक वर्ग था जहाँ सभी विधियों ने एक ही प्रक्रिया के रूपांतर किए थे - जिसके कारण लम्बी परीक्षाएँ हुईं, जिनमें से प्रत्येक केवल दूसरों से दूर ही थी। DRY एक बहुत दूर का सपना था।

सोचा कि मुझे सभी तरीकों के लिए एक ही परीक्षण करना चाहिए, इसलिए मैंने उपरोक्त पुनरावृत्ति की।

हालांकि मुझे एहसास हुआ कि मुझे इसके बजाय कोड को DRY- कंप्लेंट होने के लिए फिर से रिफ्लेक्टर करना चाहिए ... यह अभी भी भविष्य में एक यादृच्छिक नाइटपिक आत्मा की सेवा कर सकता है।


2

मैं इसे वहीं रखता हूं, क्योंकि टॉप रेटेड उत्तर स्पष्ट नहीं हैं

यह Enum पर आधारित सामान्य वर्ग नहीं के साथ सरल परीक्षा है।

# -*- coding: utf-8 -*-
import sys, inspect
from enum import Enum

class my_enum(Enum):
    """Enum base class my_enum"""
    M_ONE = -1
    ZERO = 0
    ONE = 1
    TWO = 2
    THREE = 3

    def is_natural(self):
            return (self.value > 0)
    def is_negative(self):
            return (self.value < 0)

def is_clean_name(name):
    return not name.startswith('_') and not name.endswith('_')
def clean_names(lst):
    return [ n for n in lst if is_clean_name(n) ]
def get_items(cls,lst):
    try:
            res = [ getattr(cls,n) for n in lst ]
    except Exception as e:
            res = (Exception, type(e), e)
            pass
    return res


print( sys.version )

dir_res = clean_names( dir(my_enum) )
inspect_res = clean_names( [ x[0] for x in inspect.getmembers(my_enum) ] )
dict_res = clean_names( my_enum.__dict__.keys() )

print( '## names ##' )
print( dir_res )
print( inspect_res )
print( dict_res )

print( '## items ##' )
print( get_items(my_enum,dir_res) )
print( get_items(my_enum,inspect_res) )
print( get_items(my_enum,dict_res) )

और यह आउटपुट परिणाम है।

3.7.7 (default, Mar 10 2020, 13:18:53) 
[GCC 9.2.1 20200306]
## names ##
['M_ONE', 'ONE', 'THREE', 'TWO', 'ZERO']
['M_ONE', 'ONE', 'THREE', 'TWO', 'ZERO', 'name', 'value']
['is_natural', 'is_negative', 'M_ONE', 'ZERO', 'ONE', 'TWO', 'THREE']
## items ##
[<my_enum.M_ONE: -1>, <my_enum.ONE: 1>, <my_enum.THREE: 3>, <my_enum.TWO: 2>, <my_enum.ZERO: 0>]
(<class 'Exception'>, <class 'AttributeError'>, AttributeError('name'))
[<function my_enum.is_natural at 0xb78a1fa4>, <function my_enum.is_negative at 0xb78ae854>, <my_enum.M_ONE: -1>, <my_enum.ZERO: 0>, <my_enum.ONE: 1>, <my_enum.TWO: 2>, <my_enum.THREE: 3>]

तो हमारे पास क्या है:

  • dir पूरा डेटा उपलब्ध नहीं है
  • inspect.getmembers पूरा डेटा नहीं देते हैं और उन आंतरिक कुंजियों को प्रदान करते हैं जो सुलभ नहीं हैं getattr()
  • __dict__.keys()पूर्ण और विश्वसनीय परिणाम प्रदान करें

वोट इतने गलत क्यों हैं? और मैं कहां गलत हूं? और कहां गलत अन्य लोगों के जवाब जिनके पास इतने कम वोट हैं?


1
methods = [(func, getattr(o, func)) for func in dir(o) if callable(getattr(o, func))]

के रूप में एक समान सूची देता है

methods = inspect.getmembers(o, predicate=inspect.ismethod)

कर देता है।


0

यदि आपकी विधि एक "नियमित" विधि है और नहीं statimethod, classmethodआदि।
वहाँ एक छोटा सा हैक मैं के साथ आया है -

for k, v in your_class.__dict__.items():
    if "function" in str(v):
        print(k)

यह इसी प्रकार से ifस्थिति में "फ़ंक्शन" को बदलकर अन्य प्रकार के तरीकों के लिए बढ़ाया जा सकता है ।
अजगर 2.7 पर परीक्षण किया गया।


1
यकीन नहीं हो रहा था कि इसे क्यों उतारा गया ... यह वास्तव में उस समस्या को हल करता है जो मैं कर रहा था।
redspidermkv

0

आप निम्न कोड का उपयोग करके अजगर वर्ग में सभी तरीकों को सूचीबद्ध कर सकते हैं

dir(className)

यह कक्षा में विधियों के सभी नामों की सूची लौटाएगा


-1

मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन अभी इस फंक्शन को लिखा है और इसे यहां छोड़ दूंगा अगर कोई व्यक्ति उत्तर की तलाश में ठोकर खाए:

def classMethods(the_class,class_only=False,instance_only=False,exclude_internal=True):

    def acceptMethod(tup):
        #internal function that analyzes the tuples returned by getmembers tup[1] is the 
        #actual member object
        is_method = inspect.ismethod(tup[1])
        if is_method:
            bound_to = tup[1].im_self
            internal = tup[1].im_func.func_name[:2] == '__' and tup[1].im_func.func_name[-2:] == '__'
            if internal and exclude_internal:
                include = False
            else:
                include = (bound_to == the_class and not instance_only) or (bound_to == None and not class_only)
        else:
            include = False
        return include
    #uses filter to return results according to internal function and arguments
    return filter(acceptMethod,inspect.getmembers(the_class))

यह कोड वैसा नहीं करता जैसा कि इसे प्रकाशित करने का इरादा है। Class_only या inst_only देने से रिक्त सूची आएगी।
ओजस्वी १२

-2

यह सिर्फ एक अवलोकन है। "एन्कोड" स्ट्रिंग वस्तुओं के लिए एक विधि प्रतीत होती है

str_1 = 'a'
str_1.encode('utf-8')
>>> b'a'

हालांकि, अगर str1 का निरीक्षण तरीकों के लिए किया जाता है, तो एक खाली सूची वापस आ जाती है

inspect.getmember(str_1, predicate=inspect.ismethod)
>>> []

इसलिए, शायद मैं गलत हूं, लेकिन यह मुद्दा सरल नहीं है।


1
'a'एक वस्तु है, जिसका प्रकार है str। आप इसे चलाकर देख सकते हैं type('a')inspect.getmember()एक प्रकार का पैरामीटर लेता है, इसलिए आपको inspect.getmember(str)यह देखने के लिए कॉल करने की आवश्यकता है कि आप क्या अपेक्षा करते हैं।
lhasson

-3
class CPerson:
    def __init__(self, age):
        self._age = age

    def run(self):
        pass

    @property
    def age(self): return self._age

    @staticmethod
    def my_static_method(): print("Life is short, you need Python")

    @classmethod
    def say(cls, msg): return msg


test_class = CPerson
# print(dir(test_class))  # list all the fields and methods of your object
print([(name, t) for name, t in test_class.__dict__.items() if type(t).__name__ == 'function' and not name.startswith('__')])
print([(name, t) for name, t in test_class.__dict__.items() if type(t).__name__ != 'function' and not name.startswith('__')])

उत्पादन

[('run', <function CPerson.run at 0x0000000002AD3268>)]
[('age', <property object at 0x0000000002368688>), ('my_static_method', <staticmethod object at 0x0000000002ACBD68>), ('say', <classmethod object at 0x0000000002ACF0B8>)]

-4

यदि आप एक अजगर वर्ग के केवल तरीकों को सूचीबद्ध करना चाहते हैं

import numpy as np
print(np.random.__all__)

1
यह एक मॉड्यूल है, एक वर्ग नहीं है।
अरन-फे

@ अरन-फे यह हर वर्ग के लिए लागू होता है, सभी हर वर्ग में मौजूद है
राकेश चौधरी

2
नहीं, यह नहीं है। यह सभी मॉड्यूल में मौजूद नहीं है ।
अरन-फे
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.