2009-05-07 27 views
60

मेरे पास एक दिनचर्या है जो पैरामीटर के रूप में तारों की एक सूची लेती है, लेकिन मैं एक स्ट्रिंग में गुजरने और इसे एक स्ट्रिंग की सूची में बदलने का समर्थन करना चाहता हूं। उदाहरण के लिए:मैं कैसे बता सकता हूं कि एक अजगर चर एक स्ट्रिंग या एक सूची है या नहीं?

def func(files): 
    for f in files: 
     doSomethingWithFile(f) 

func(['file1','file2','file3']) 

func('file1') # should be treated like ['file1'] 

मेरा कार्य कैसे बता सकता है कि कोई स्ट्रिंग या सूची पारित की गई है या नहीं? मुझे पता है कि type फ़ंक्शन है, लेकिन क्या वहां "अधिक पायथनिक" तरीका है?

उत्तर

36

ठीक है, जांच प्रकार के बारे में कुछ भी अस्पष्ट नहीं है। करने के बाद कहा कि, अगर आप फोन करने वाले पर एक छोटा सा बोझ डाल करने के लिए तैयार हैं:

def func(*files): 
    for f in files: 
     doSomethingWithFile(f) 

func(*['file1','file2','file3']) #Is treated like func('file1','file2','file3') 
func('file1') 

मैं बहस चाहते हैं यह है कि में और अधिक pythonic "स्पष्ट अंतर्निहित से बेहतर है" है। कॉलर के हिस्से पर कम से कम एक मान्यता है जब इनपुट पहले ही सूची में है।

+9

निश्चित रूप से अधिक "स्पष्ट" विधि उपयोगकर्ता को सूची में सिंगल-फ़ाइल पास करने की आवश्यकता होगी? Func की तरह (['file1']) – dbr

+1

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

43
isinstance(your_var, basestring) 
+3

इस समाधान को कुछ स्पष्टीकरण की आवश्यकता है, कुछ संदर्भ। न तो your_var और न ही बेसस्ट्रिंग ओपी के पोस्ट में हैं। –

+2

यह पायथन 3 से काम नहीं करता है। 'Isinstance (your_var, str)' का उपयोग करें। –

32

व्यक्तिगत रूप से, मुझे वास्तव में इस प्रकार के व्यवहार को पसंद नहीं है - यह बतख टाइपिंग में हस्तक्षेप करता है। कोई तर्क दे सकता है कि यह "स्पष्ट से स्पष्ट स्पष्ट" मंत्र का पालन नहीं करता है। varargs सिंटैक्स का उपयोग क्यों नहीं:

def func(*files): 
    for f in files: 
     doSomethingWithFile(f) 

func('file1', 'file2', 'file3') 
func('file1') 
func(*listOfFiles) 
+1

"व्यक्तिगत रूप से, मुझे वास्तव में इस प्रकार के व्यवहार को पसंद नहीं है", आप विशेष रूप से क्या कह रहे हैं? –

+0

@nemo मुझे लगता है कि उसका मूल प्रश्न था, जिसे किसी फ़ंक्शन के लिए पूछने के रूप में व्याख्या किया जा सकता है जिसका पैरामीटर स्ट्रिंग या तारों की सूची है जिसमें फ़ंक्शन कॉल का कोई उल्लेख नहीं है कि किस प्रकार का पैरामीटर पारित किया गया है। मैं इसके साथ सहमत हूं । –

+0

FWIW, varargs केवल तभी काम करता है जब कोई अन्य तर्क न हो: 'func (file, someflag) 'को' func (* files, someflag) 'में परिवर्तित नहीं किया जा सकता है,' someflag' को किसी कीवर्ड arg – pjz

15

मैं कहूंगा कि सबसे Python'y तरह से उपयोगकर्ता हमेशा एक सूची पारित करने के लिए है, यह में केवल एक आइटम है, भले ही। यह यह वास्तव में स्पष्ट func()

def func(files): 
    for cur_file in files: 
     blah(cur_file) 

func(['file1']) 

के रूप में डेव सुझाव दिया है, तो आप func(*files) वाक्य रचना इस्तेमाल कर सकते हैं फ़ाइलों की एक सूची ले जा सकते हैं बनाता है, लेकिन मैं इस सुविधा पसंद आया कभी नहीं, और इसे और अधिक स्पष्ट लगता है ("स्पष्ट अंतर्निहित से बेहतर है") बस एक सूची की आवश्यकता है। यह भी अपने विशेष-केस डिफ़ॉल्ट मामले में (एक एकल फाइल के साथ func बुला) घूम रहा है, क्योंकि अब आप अतिरिक्त सिंटैक्स का उपयोग करने के लिए एक सूची के साथ func कॉल करनी होगी ..

आप एक विशेष मामला बनाने के लिए चाहते हैं, तो एक तर्क एक स्ट्रिंग होने के लिए, isinstance() builtin उपयोग करें, और basestring उदाहरण के लिए (जो दोनों str() और unicode() से प्राप्त कर रहे) की तुलना:, यहां तक ​​कि केवल एक फ़ाइल के साथ (

def func(files): 
    if isinstance(files, basestring): 
     doSomethingWithASingleFile(files) 
    else: 
     for f in files: 
      doSomethingWithFile(f) 

वास्तव में, मैं बस एक सूची की आवश्यकता होती है की सलाह देते हैं आखिरकार, केवल दो अतिरिक्त पात्रों की आवश्यकता है!)

+10

में बदल दिए बिना समस्या यह है कि यदि आप केवल यहां बतख टाइपिंग पर भरोसा करते हैं, तो एक स्ट्रिंग * को * बतख टाइपिंग वाली सूची की तरह माना जाता है, और सही काम नहीं करता है। इसे एक ही आइटम की तरह इलाज करने के बजाय, अजगर स्ट्रिंग को वर्णों की सूची की तरह व्यवहार करेगा। Whups। –

10
if hasattr(f, 'lower'): print "I'm string like" 
+0

एक बहुत ही सरल समाधान जो मेरे लिए पूरी तरह से काम करता था। धन्यवाद! –

+3

जो तब तक काम करता है जब तक कोई व्यक्ति आपको 'निचली' विधि के साथ संग्रह नहीं देता है: -/ – AlexChaffee

+1

^जैसे कि गणितीय वस्तु, या एक वास्तविक दुनिया फ़ंक्शन के साथ इंटरफेस करता है जैसे कि यांत्रिक रूप से नियंत्रित विंडो को ऊपर उठाना या कम करना। :) –

3

वरर्ग मेरे लिए भ्रमित था, इसलिए मैंने इसे अपने लिए साफ़ करने के लिए पायथन में इसका परीक्षण किया।

varargs के लिए सभी पीईपी here है।

यहां डेव और डेविड बर्गर के दो उत्तरों के आधार पर नमूना कार्यक्रम है, इसके बाद आउटपुट के बाद, स्पष्टीकरण के लिए।

def func(*files): 
    print files 
    for f in files: 
     print(f) 

if __name__ == '__main__': 
    func(*['file1','file2','file3']) #Is treated like func('file1','file2','file3') 
    func('onestring') 
    func('thing1','thing2','thing3') 
    func(['stuff1','stuff2','stuff3']) 

और परिणामी आउटपुट;

('file1', 'file2', 'file3') 
file1 
file2 
file3 
('onestring',) 
onestring 
('thing1', 'thing2', 'thing3') 
thing1 
thing2 
thing3 
(['stuff1', 'stuff2', 'stuff3'],) 
['stuff1', 'stuff2', 'stuff3'] 

आशा है कि यह किसी और के लिए सहायक होगा।

10
def func(files): 
    for f in files if not isinstance(files, basestring) else [files]: 
     doSomethingWithFile(f) 

func(['file1', 'file2', 'file3']) 

func('file1') 
+0

पीओपी 8 प्रकार मॉड्यूल का उपयोग करने के बजाय isinstance (u'abc ', basestring) पसंद करती है। – max

+0

@mdorseif: मैंने 'प्रकार' मॉड्यूल के बजाय 'बेसस्ट्रिंग' का उपयोग करने के लिए उत्तर संपादित किया है। – jfs

6

यदि आपके पास कॉलर पर अधिक नियंत्रण है, तो अन्य उत्तरों में से एक बेहतर है। मैं मेरे मामले में है कि लक्जरी नहीं है तो मैं निम्नलिखित समाधान (कैविएट्स के साथ) पर बसे:

def islistlike(v): 
    """Return True if v is a non-string sequence and is iterable. Note that 
    not all objects with getitem() have the iterable attribute""" 
    if hasattr(v, '__iter__') and not isinstance(v, basestring): 
     return True 
    else: 
     #This will happen for most atomic types like numbers and strings 
     return False 

यह दृष्टिकोण मामलों में आप किसी पता सूची की तरह प्रकार है कि पूरा का सेट के साथ काम कर रहे हैं के लिए काम करेंगे उपर्युक्त मानदंड हालांकि कुछ अनुक्रम प्रकार याद किए जाएंगे।

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

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