नाम से अजगर विधि को बुलाओ


82

यदि मेरे पास एक स्ट्रिंग में एक ऑब्जेक्ट और एक विधि का नाम है, तो मैं विधि को कैसे कह सकता हूं?

class Foo:
    def bar1(self):
        print 1
    def bar2(self):
        print 2

def callMethod(o, name):
    ???

f = Foo()
callMethod(f, "bar1")

1
हालांकि वे समान हैं, यह इस सवाल का एक सटीक डुप्लिकेट नहीं है , जो किसी वस्तु की विधि के बजाय एक मॉड्यूल में एक फ़ंक्शन के बारे में पूछता है।
— ग्रुमड्रिग 20

बहुत बारीकी से संबंधित (हेक, शायद यहां तक ​​कि डुबकी): उस विशेषता के नाम के अनुरूप स्ट्रिंग दी गई वस्तु विशेषता तक कैसे पहुंचें । विधियाँ भी विशेषताएँ हैं।
— अरन-फे

जवाबों:


113

अंतर्निहित getattr()फ़ंक्शन का उपयोग करें :

class Foo:
    def bar1(self):
        print(1)
    def bar2(self):
        print(2)

def call_method(o, name):
    return getattr(o, name)()


f = Foo()
call_method(f, "bar1")  # prints 1

आप setattr()नाम से वर्ग विशेषताओं की स्थापना के लिए भी उपयोग कर सकते हैं ।


मुझे पता नहीं चला कि दस्तावेज में क्या खोजना है! धन्यवाद!
— जैज

@ जैज, यह बिलिन के अधीन है। आपको एक पेज पर खोज C-f
— करनी होगी

@aronasterling मुझे पता है, लेकिन मुझे नहीं पता था कि किस शब्द को खोजना है!
— जाज

Why callMethod (f, "bar1") को f.callMethod (f, "bar1") नहीं कहा जाता है
— फिलिप पुथेनविला

PhilipJ, क्योंकि यह सिर्फ एक विधि है जो पहले एक पंक्ति को परिभाषित करता है, फू: वर्ग के बाहर।
— एनरिको कारलेसो

6

मेरे पास इसी तरह का प्रश्न था, उदाहरण के लिए संदर्भ विधि को कॉल करना चाहता था। यहाँ मजेदार चीजें हैं जो मैंने पाया:

instance_of_foo=Foo()

method_ref=getattr(Foo, 'bar')
method_ref(instance_of_foo) # instance_of_foo becomes self

instance_method_ref=getattr(instance_of_foo, 'bar')
instance_method_ref() # instance_of_foo already bound into reference

अजगर अद्भुत है!


2
getattr(globals()['Foo'](), 'bar1')()
getattr(globals()['Foo'](), 'bar2')()

पहले फू फूंकने की जरूरत नहीं!


यह केवल एक उदाहरण था, मेरे पास वास्तविक वर्ग का वास्तविक उदाहरण है!
— जैज

2
एक असंगठित वर्ग का एक तरीका कहलाना शायद इसका मतलब है कि आप कुछ गलत कर रहे हैं।
— एनरिको कारलेसो

क्या हुआ अगर fooग्लोबल्स में नहीं है?
— एरोनस्टरलिंग

1
यह शायद नहीं है, लेकिन आप देखभाल कि ले जाना चाहिए Fooहै। ;)
— जॉन्डोडो


0

यहां पायथन डेकोरेटर्स का उपयोग करके एक अधिक सामान्यीकृत संस्करण है। आप छोटे या लंबे नाम से पुकार सकते हैं। सीएलआई को छोटी और लंबी उप कमांडों के साथ लागू करते समय मुझे यह उपयोगी लगा।

अजगर सज्जाकार अद्भुत हैं। ब्रूस एकेल (जावा में सोच) ने यहां के पायथन सज्जाकारों का खूबसूरती से वर्णन किया है।

http://www.artima.com/weblogs/viewpost.jsp?thread=240808 http://www.artima.com/weblogs/viewpost.jsp?thread=240845

#!/usr/bin/env python2

from functools import wraps


class CommandInfo(object):
    cmds = []

    def __init__(self, shortname, longname, func):
        self.shortname = shortname
        self.longname = longname
        self.func = func


class CommandDispatch(object):
    def __init__(self, shortname, longname):
        self.shortname = shortname
        self.longname = longname

    def __call__(self, func):
        print("hello from CommandDispatch's __call__")

        @wraps(func)
        def wrapped_func(wself, *args, **kwargs):
            print('hello from wrapped_func, args:{0}, kwargs: {1}'.format(args, kwargs))
            func(wself, *args, **kwargs)

        ci = CommandInfo
        ci.cmds += [ci(shortname=self.shortname, longname=self.longname, func=func)]
        return wrapped_func

    @staticmethod
    def func(name):
        print('hello from CommandDispatch.func')

        for ci in CommandInfo.cmds:
            if ci.shortname == name or ci.longname == name:
                return ci.func

        raise RuntimeError('unknown command')


@CommandDispatch(shortname='co', longname='commit')
def commit(msg):
    print('commit msg: {}'.format(msg))


commit('sample commit msg')         # Normal call by function name

cd = CommandDispatch
short_f = cd.func(name='co')        # Call by shortname
short_f('short sample commit msg')

long_f = cd.func(name='commit')     # Call by longname
long_f('long sample commit msg')


class A(object):
    @CommandDispatch(shortname='Aa', longname='classAmethoda')
    def a(self, msg):
        print('A.a called, msg: {}'.format(msg))


a = A()
short_fA = cd.func(name='Aa')
short_fA(a, 'short A.a msg')

long_fA = cd.func(name='classAmethoda')
long_fA(a, 'short A.a msg')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.