2010-04-21 8 views
42

इस तरह मान लीजिए कोड:ऑब्जेक्ट्स की सूची के लिए एक ही विधि को कैसे कॉल करें?

class Base: 
    def start(self): 
     pass 
    def stop(self) 
     pass 

class A(Base): 
    def start(self): 
     ... do something for A 
    def stop(self) 
     .... do something for A 

class B(Base): 
    def start(self): 

    def stop(self): 

a1 = A(); a2 = A() 
b1 = B(); b2 = B() 

all = [a1, b1, b2, a2,.....] 

अब मैं तरीकों शुरू फोन और सभी की सूची में प्रत्येक वस्तु के लिए रोक (शायद भी अन्य) करना चाहते हैं। वहाँ की तरह

def start_all(all): 
    for item in all: 
     item.start() 

def stop_all(all): 
+1

समारोह का एक समूह दो समारोह है में? – SilentGhost

+3

यह आपके प्रश्न से असंबंधित नहीं है, लेकिन आपके उदाहरण में कोई स्पष्ट कारण नहीं है कि आपको उस बेस क्लास की आवश्यकता क्यों है। पाइथन आपको असंबद्ध वस्तुओं की एक सूची देने के लिए बहुत खुश होंगे और जब तक कि सभी के पास 'स्टार्ट' और 'स्टॉप' विधियां हों, तब भी आप विधियों को कॉल करने के माध्यम से फिर से चल सकते हैं। – Duncan

+1

आपकी परिभाषित 'बेस' बेकार विधियों के साथ और फिर' ए 'और' बी 'में व्यवहार को परिभाषित करने से पाइथन में एक खराब डिज़ाइन दर्शाता है। एक अमूर्त बेस क्लास का उपयोग करने के बजाय, आप केवल 'ए' और 'बी' को परिभाषित कर सकते हैं और इंटरफ़ेस साझा करते समय उन्हें एक दूसरे के रूप में उपयोग कर सकते हैं। चीजों को करने का आपका वर्तमान तरीका एक बेकार वर्ग बनाता है, जो केवल अतिरिक्त सामान है जिसकी आपको आवश्यकता नहीं है। –

उत्तर

3

* _all() फ़ंक्शंस इतना आसान हैं कि कुछ तरीकों के लिए मैं केवल फ़ंक्शन लिखूंगा। आप समान कार्यों के बहुत सारे है, तो आप एक सामान्य समारोह लिख सकते हैं:

def apply_on_all(seq, method, *args, **kwargs): 
    for obj in seq: 
     getattr(obj, method)(*args, **kwargs) 

या एक समारोह कारखाना बनाने के लिए:

def create_all_applier(method, doc=None): 
    def on_all(seq, *args, **kwargs): 
     for obj in seq: 
      getattr(obj, method)(*args, **kwargs) 
    on_all.__doc__ = doc 
    return on_all 

start_all = create_all_applier('start', "Start all instances") 
stop_all = create_all_applier('stop', "Stop all instances") 
... 
+27

यह मुझे लूप के लिए सीधे लिखने से सरल नहीं है। –

6

शायद map कार्यों का एक गुच्छा लिखने के सिवाय ऐसा करने के लिए किसी भी सुरुचिपूर्ण रास्ता नहीं है, लेकिन जब से तुम एक सूची बनाने के लिए नहीं करना चाहते, तो आप अपने ... लिख सकते हैं

def call_for_all(f, seq): 
    for i in seq: 
     f(i) 

तो आप कर सकते हैं:

call_for_all(lamda x: x.start(), all) 
call_for_all(lamda x: x.stop(), all) 

वैसे, सभी एक समारोह में बनाया गया है, यह ऊपर लिख नहीं है ;-)

14

दृष्टिकोण

for item in all: 
    item.start() 

सरल, आसान है, पठनीय , और संक्षेप में। यह मुख्य दृष्टिकोण पायथन इस ऑपरेशन के लिए प्रदान करता है। यदि आप कुछ मदद करते हैं तो आप निश्चित रूप से इसे फ़ंक्शन में encapsulate कर सकते हैं। सामान्य उपयोग के लिए इसके लिए एक विशेष समारोह को परिभाषित करने के लिए केवल लूप को लिखने से कम स्पष्ट होने की संभावना है।

2

ले रहा है @Ants Aasmas का जवाब एक कदम आगे, आप एक आवरण है कि किसी भी विधि कॉल लेता है और एक दी गई सूची के सभी तत्वों को फ़ॉरवर्ड पर बना सकते हैं:

class AllOf: 
    def __init__(self, elements): 
     self.elements = elements 
    def __getattr__(self, attr): 
     def on_all(*args, **kwargs): 
      for obj in self.elements: 
       getattr(obj, attr)(*args, **kwargs) 
     return on_all 

यही वर्ग तो इस तरह इस्तेमाल किया जा सकता:

class Foo: 
    def __init__(self, val="quux!"): 
     self.val = val 
    def foo(self): 
     print "foo: " + self.val 

a = [ Foo("foo"), Foo("bar"), Foo()] 
AllOf(a).foo() 

निम्नलिखित में से कौन उत्पादन का उत्पादन:

foo: foo 
foo: bar 
foo: quux!

कुछ काम के साथ और आसानी से गुणों को संभालने के लिए इसे बढ़ाया जा सकता है (विशेषता मानों की एक सूची लौटा रहा है)।

18

ऐसा लगता है कि ऐसा करने का एक और पाइथोनिक तरीका होगा, लेकिन मुझे अभी तक यह नहीं मिला है।

मैं "मानचित्र" कभी कभी अगर मैं वस्तुओं का एक समूह पर एक ही समारोह (नहीं एक विधि) फोन कर रहा हूँ का उपयोग करें:

map(do_something, a_list_of_objects) 

इस कोड का एक समूह की जगह है कि इस तरह दिखता है:

do_something(a) 
do_something(b) 
do_something(c) 
... 

लेकिन यह भी पाश "के लिए" एक पैदल यात्री के साथ प्राप्त किया जा सकता है:

for obj in a_list_of_objects: 
     do_something(obj) 

नकारात्मक पक्ष यह है कि एक) आप कर रहे हैं है "मानचित्र" से वापसी मूल्य के रूप में एक सूची बना रही है जिसे केवल फेंक दिया जा रहा है और बी) यह अधिक भ्रमित हो सकता है कि केवल सरल लूप संस्करण।

तुम भी एक सूची समझ इस्तेमाल कर सकते हैं, लेकिन यह थोड़ा अपमानजनक के रूप में अच्छी तरह से (एक बार फिर से, एक थ्रो-दूर सूची बनाने) है:

[ do_something(x) for x in a_list_of_objects ] 

तरीकों के लिए, मैं इनमें से किसी काम करेगा लगता है (के साथ एक ही आरक्षण):

map(lambda x: x.method_call(), a_list_of_objects) 

या

[ x.method_call() for x in a_list_of_objects ] 

तो, वास्तव में, मैं पी लगता है एड्रियन (अभी तक प्रभावी) "लूप के लिए" शायद आपकी सबसे अच्छी शर्त है।

+3

मेरी पहली प्रतिक्रिया मानचित्र थी (लैम्ब्डा x: x.member(), सूची)। यह एक सुंदर स्पष्ट एक लाइनर की तरह महसूस किया –

100

यह काम करेंगे

all = [a1, b1, b2, a2,.....] 

map(lambda x: x.start(),all)  

सरल उदाहरण

all = ["MILK","BREAD","EGGS"] 
map(lambda x:x.lower(),all) 
>>>['milk','bread','eggs'] 

और python3

all = ["MILK","BREAD","EGGS"] 
list(map(lambda x:x.lower(),all)) 
>>>['milk','bread','eggs'] 
+2

पायथन 3 मानचित्र में पाइथन 2 की तरह एक सूची वस्तु नहीं है, मुझे मानक प्रक्रिया की जानकारी नहीं है, लेकिन मैंने सोचा कि मुझे इसे सही करना चाहिए, इसलिए मैंने एक संपादन सबमिट किया। तो कोड अब पाइथन 2 और पायथन 3 में अपेक्षित और सही तरीके से काम करना चाहिए। – leetNightshade

+1

यह भी अधिक पाइथोनिक उत्तर की तरह लगता है, यह स्वीकार किया जाना चाहिए। नक्शा एक अच्छी पसंद है, और मैंने पहले कभी लैम्बडा का उपयोग नहीं किया है, इसलिए धन्यवाद। – leetNightshade

+0

ने पायथन 3 का अधिक उपयोग नहीं किया है, लेकिन एक अधिक सामान्य समाधान को चोट नहीं पहुँचना चाहिए (और मुझे नहीं लगता कि यह उदाहरण को कम स्पष्ट करता है)। असल में मुझे पिछले साल से जितना चाहें उतना पाइथन के साथ काम करने का मौका नहीं मिला है। –

संबंधित मुद्दे