পাইথন ক্লাসে আমি কীভাবে পদ্ধতির তালিকা পেতে পারি?


329

আমি একটি ক্লাসে পদ্ধতিগুলির মাধ্যমে পুনরাবৃত্তি করতে চাই, বা উপস্থিত পদ্ধতিগুলির উপর ভিত্তি করে শ্রেণি বা উদাহরণ আইটেমগুলি ভিন্নভাবে পরিচালনা করতে চাই। আমি কীভাবে ক্লাস পদ্ধতির একটি তালিকা পেতে পারি?

আরও দেখুন:


1
উত্স ..... উত্স ...
রিকিএ

4
@ জোনক্রোয়েল যে ফোর্সটি কীভাবে কাজ করে তা তা নয়।
কেন উইলিয়ামস

Cython কম্পাইলার নির্দেশ ব্যবহার করার জন্য bindingকাজ করে: stackoverflow.com/a/46041480/1959808
Ioannis Filippidis

4
পাইথন 3-তে: [f for f in dir(ClassName) if not f.startswith('_')]বা কেবলমাত্র dir(ClassName)সমস্ত কিছুর জন্য
সেরাফ

@ সিরাফ দয়া করে মন্তব্যগুলিতে উত্তর পোস্ট করবেন না। পরিবর্তে একটি উত্তর পোস্ট করুন।
wjandrea

উত্তর:


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
অজগর
7.7

222

নেই dir(theobject)তালিকা সব ক্ষেত্র এবং আপনার বস্তুর পদ্ধতি (ক tuple হিসেবে) পদ্ধতি এবং মডিউল পরিদর্শন (codeape write বৈশিষ্ট্যসহ) ( "মধ্যে" ") ক্ষেত্র এবং তাদের ডক সঙ্গে পদ্ধতি তালিকা।

যেহেতু পাইথনে সমস্ত কিছু (এমনকি ক্ষেত্রগুলি) ডাকা হতে পারে, আমি নিশ্চিত না যে কেবলমাত্র পদ্ধতিগুলির তালিকা তৈরি করার জন্য একটি অন্তর্নির্মিত ফাংশন রয়েছে। আপনি চেষ্টা করতে পারেন আপনি যে বস্তুর মাধ্যমে পাচ্ছেন dirসেটি কলযোগ্য কিনা ।


3
dir (অবজেক্ট) হ'ল আমি যে সহজ সমাধানটি ব্যবহার করেছি।
lstodd

1
এটি গৃহীত সমাধান থেকে কীভাবে আলাদা?
skjerns

@ এসকিঞ্জারস এটি টাইপ করতে 5 টি প্রতীক লাগে। :)
Dr_Zaszuś

117

বাইরের লাইব্রেরি ছাড়াই পাইথন ৩.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

বলুন যে আপনি তালিকা বর্গের সাথে জড়িত সমস্ত পদ্ধতি জানতে চান নীচের নীচেরটি Type

 print (dir(list))

উপরে তালিকা তালিকার সমস্ত পদ্ধতি আপনাকে দেবে


2
এটিই সেরা সমাধান
জিশান আহমদ

3
print([ m for m in dir(my_class) if not m.startswith('__')])
ইভহ্জেড

32

সম্পত্তি চেষ্টা করুন __dict__


16
আমি মনে করি আপনি ডিক মানে । কিন্তু এটি উদাহরণগুলির বৈশিষ্ট্যগুলি তালিকাভুক্ত করে, পদ্ধতিগুলি নয়।
me_ এবং

1
… এটি আমার পক্ষেও কার্যকর হয়নি। মার্কডাউন সিনট্যাক্সের সাথে পরামর্শ করার পরে, আমি মনে করি আমার অর্থ __ডিক্ট__।
me_ এবং

3
@ মি_আপনি সম্ভবত সম্ভবত "স্ব .__ ডিক__" করছেন বা আরও সাধারণভাবে, উদাহরণ সংস্করণটিকে কল করছেন __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__এবং ব্যক্তিগত পদ্ধতি উপেক্ষা করার জন্য আমি তালিকা বোধের শেষে যুক্ত করেছিলাম of
ক্রিস্টোফার পিয়ারসন

2
আপনি পরিত্রাণ পেতে পারেন importএর FunctionTypeসঙ্গে একটি বিজ্ঞাপন ল্যামডা ব্যবহার করে 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 এর ইন্ডেন্টেশন? মূলশব্দ মূলশব্দটি? নন-পিপ 8-স্টাইলের ব্যবধান?
ফ্লোরিরি

1
কোডিং কনভেনশন নাজিস একবারও পেল না!
rbennell

1
কিভাবে এই প্রশ্নের উত্তর দেয়?
অরণ-ফে

2

এই পদ্ধতির আছে:

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

শ্রেণীর উদাহরণের সাথে কাজ করার সময়, কেবলমাত্র নামগুলির পরিবর্তে পদ্ধতি রেফারেন্স সহ একটি তালিকা ফেরত দেওয়া ভাল ¹ যদি এটি আপনার লক্ষ্যও হয় তবে

  1. না import
  2. __init__তালিকা থেকে ব্যক্তিগত পদ্ধতি (উদাঃ ) বাদ দেওয়া Exc

এটি ব্যবহার হতে পারে। সংক্ষেপে, একটি শ্রেণীর জন্য

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 একটি ব্যবহারের কেস:

আমি ইউনিট পরীক্ষার জন্য এটি ব্যবহার করেছি । একটি ক্লাস ছিল যেখানে সমস্ত পদ্ধতি একই প্রক্রিয়াটির বিভিন্নতা সম্পাদন করে - যার ফলে দীর্ঘতর পরীক্ষাগুলি পরিচালিত হয়েছিল, প্রতিটি একে অপরের থেকে কেবল একটি টুইটের দূরে। ডিআরওয়াই ছিল অনেক দূরের স্বপ্ন।

ভেবেছিলাম আমার সকল পদ্ধতির জন্য একটি একক পরীক্ষা করা উচিত, তাই আমি উপরের পুনরাবৃত্তিটি করেছি।

যদিও আমি বুঝতে পেরেছিলাম তার পরিবর্তে আমার উচিত চুল্লী কোডটি নিজেই ডিআরওয়াই-কমপ্লায়েন্ট হওয়ার জন্য ... এটি ভবিষ্যতে এখনও এলোমেলোভাবে নিটপিক আত্মাকে পরিবেশন করতে পারে।


2

আমি কেবল এটি সেখানে রাখছি, কারণ শীর্ষ রেট করা উত্তরগুলি পরিষ্কার নয়

এটি এনামের উপর ভিত্তি করে সাধারণ শ্রেণীর সাথে সহজ পরীক্ষা simple

# -*- 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ইত্যাদি
There

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

ifশর্তে অনুরূপভাবে "ফাংশন" পরিবর্তন করে এটি অন্যান্য ধরণের পদ্ধতিতে প্রসারিত হতে পারে ।
অজগর ২.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))

এই কোডটি এটি প্রকাশিত হিসাবে যা ইচ্ছা তা করে না। ক্লাস_অনলি বা ইনস্ট্যান্স_অনলি দেওয়ার ফলে খালি তালিকার ফলাফল।
ওজ 123

-2

এটি কেবল একটি পর্যবেক্ষণ। "এনকোড" স্ট্রিং অবজেক্টগুলির জন্য একটি পদ্ধতি বলে মনে হচ্ছে

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

তবে, str1 পদ্ধতিগুলির জন্য পরীক্ষা করা হলে, একটি খালি তালিকা ফিরে আসে list

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

সুতরাং, সম্ভবত আমি ভুল, কিন্তু বিষয়টি সহজ বলে মনে হচ্ছে না।


1
'a'এমন একটি বস্তু, যার প্রকার str। দৌড়ে আপনি এটি দেখতে পারেন type('a')inspect.getmember()একধরণের প্যারামিটার লাগে, তাই আপনি inspect.getmember(str)কী আশা করেন তা দেখতে আপনাকে কল করতে হবে।
লাসন

-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
না, তা হয় না। এমনকি এটি সমস্ত মডিউলে বিদ্যমান নেই ।
অরণ-ফে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.