2011-04-18 11 views
14

में सरणी सूचकांक द्वारा कार्यों कॉलिंग मैं अजगर out1, out2, out3 आदि में कार्य का एक समूह है और उन्हें एक पूर्णांक मैं में पारित के आधार पर कॉल करने के लिए करना चाहते हैं।अजगर

def arryofPointersToFns (value): 
    #call outn where n = value 

वहाँ एक आसान है ऐसा करने का तरीका?

उत्तर

28

tl; dr: out1(), out2(), ..., outN() के बजाय out(n) फ़ंक्शन लिखें और इस हैक से परेशान न हों।

मैं एक उचित परिदृश्य की कल्पना नहीं कर सकता जहां यह प्रश्न अभ्यास में आएगा। कृपया समस्या के आर्किटेक्चर पर पुनर्विचार करें; ऐसा करने के लिए एक बेहतर तरीका होने की संभावना है (क्योंकि उन्हें सूची में संग्रहित करने का तात्पर्य है कि सूचकांक को छोड़कर कार्यों के बारे में कुछ भी अर्थपूर्ण नहीं है; उदाहरण के लिए, मैं केवल कल्पना कर सकता हूं कि यदि आप बना रहे थे तो आप ऐसा करना चाहते हैं गतिशील रूप से उत्पन्न थंक्स का एक गुच्छा जहां उनके अस्थायी आदेश महत्वपूर्ण हैं, या कुछ समान है)। विशेष रूप से कोई भी नौसिखिया उपयोगकर्ता जो आप इस उत्तर को पढ़ रहे हैं, एक और सामान्य कार्य करने पर विचार करें जो सब कुछ संभाल सकता है, या प्रत्येक समारोह को कुछ और पहचानने वाली जानकारी से जोड़ता है, या इसे कक्षा के हिस्से के रूप में चिपकाता है।

उस ने कहा, यह है कि आप इसे कैसे करेंगे।

myFuncs = [f0,f1,f2] 
myFuncs[2](...) #calls f2 

या

myFuncs = {'alice':f1, 'bob':f2} 
myFuncs['alice'](...) #calls f1 

इस एक कदम में सिर्फ निम्नलिखित दो कदम है:

myFuncs = [f0,f1,f2] 
f = myFuncs[i] 
f(...) #calls fi 

या आप ओपी की तरह काम करता है 'myFunc' की एक रजिस्ट्री नहीं है ऊपर कहा गया है, आप ग्लोबल्स() का उपयोग कर सकते हैं, हालांकि यह बेहद हैकिश फॉर्म है और इससे बचने के लिए (जब तक कि आप उन मॉडलों को अपने मॉड्यूल नेमस्पेस में उपलब्ध नहीं करना चाहते हैं, इस मामले में शायद यह ठीक है ... लेकिन शायद यह शायद ही कभी मामला है, और आप शायद बजाय एक submodule में उन कार्यों तो from mysubmodule import * उन्हें परिभाषित होता है, जो) थोड़ा पर सिकोड़ी बारी में है:

def fN(n): 
    return globals()['f'+str(n)] 

def f2(): 
    print("2 was called!") 

fN(2)(...) #calls f2 

यहाँ

दो अन्य विचारों (जोड़ा के बाद जवाब स्वीकार कर लिया गया और कर रहे हैं पहले दो टिप्पणियाँ):

>>> def makeRegistrar(): 
...  registry = {} 
...  def registrar(func): 
...   registry[func.__name__] = func 
...   return func # normally a decorator returns a wrapped function, 
...      # but here we return func unmodified, after registering it 
...  registrar.all = registry 
...  return registrar 

और इतने की तरह उपयोग:

आप भी इस तरह एक डेकोरेटर बना सकते हैं

>>> reg = makeRegistrar() 
>>> @reg 
... def f1(a): 
... return a+1 
... 
>>> @reg 
... def f2(a,b): 
... return a+b 
... 
>>> reg.all 
{'f1': <function f1 at 0x7fc24c381958>, 'f2': <function f2 at 0x7fc24c3819e0>} 

तो आप reg.all ['f1'] को कॉल कर सकते हैं। आप अनुक्रमण का ट्रैक रखने और कर की तरह कुछ करने के लिए reg डेकोरेटर खुद को अनुकूलित कर: वैकल्पिक रूप से

registry = [] 
index = int(re.regextofindthenumber(func.__name__)) 
if not index==len(registry): 
    raise Exception('Expected def f{} but got def f{}') 
else: 
    registry[index] = func 

, globals() से बचने के लिए, आप एक वर्ग को परिभाषित कर सकते हैं:

तो
class Funcs(object): 
    def f1(): 
     ... 
    def f2(): 
     ... 
    def num(n): 
     [code goes here] 

कार्यों का अपना नंबर छोटा है , आप ['f1','f2','f3'][i] से दूर हो सकते हैं।

बेशक बिना किसी जानकारी के, इन सभी सुझावों को वास्तविक समस्या को अनदेखा कर रहे हैं: यह स्थिति कभी नहीं आनी चाहिए, और संभवतः एक गंभीर आर्किटेक्चर दोष का संकेत है, जब आप शायद कुछ (उपयोग करने के लिए) अपने उदाहरण) की तरह:

# a possibly-better world 
def out(n): 
    # output to N, whatever that means 
बजाय

# what you have now 
def out1(): 
    # output to 1 
def out2(): 
    # output to 2 
def outN(n): 
    # ??? 
+5

हालांकि बाद ही स्वीकार्य है अगर कुछ बेचारा नहीं पता था वास्तविक समाधान (पढ़ें: पहले दो और सी milar वाले) और आप वैश्विक कार्यों 'f0',' f1', आदि के साथ फंस गए हैं .. मूर्ख मत बनो। – delnan

+0

बस एक नोट, ग्लोबल्स का उपयोग आम तौर पर एक खराब योजना है। सूची में अपने कार्यों को रखना हमेशा एक बेहतर विचार है। –

+0

@ विंस्टन ईवर्ट; जैसा कि आप सुझाव देते हैं, एक सूची का उपयोग करके इसे कैसे लिखेंगे? – Weholt

0
def array(ar=[]): 
    ar = np.array(ar) 
    return ar