पाइथन में पुनरावृत्ति फ़ाइल या निर्देशिका की प्रतिलिपि बनाएँ


116

लगता है कि पायथन के पास फ़ाइलों की नकल करने के लिए फ़ंक्शंस हैं (उदाहरण के लिए shutil.copy) और डायरेक्टरी (जैसे shutil.copytree) कॉपी करने के लिए फ़ंक्शंस हैं, लेकिन मुझे ऐसा कोई फंक्शन नहीं मिला है जो दोनों को हैंडल करता हो। ज़रूर, यह जाँचना तुच्छ है कि आप किसी फ़ाइल या निर्देशिका को कॉपी करना चाहते हैं, लेकिन यह एक अजीब चूक की तरह लगता है।

क्या वास्तव में कोई मानक फ़ंक्शन नहीं है जो यूनिक्स cp -rकमांड की तरह काम करता है , यानी निर्देशिका और फ़ाइलों और प्रतियों दोनों का समर्थन करता है? पायथन में इस समस्या के आसपास काम करने का सबसे सुरुचिपूर्ण तरीका क्या होगा?


3
हां, यह गड़बड़ है। उन स्थानों में से एक, जहां अंतर्निहित सिस्टम कॉल को प्रतिबिंबित करने की कोशिश करके, पायथन दृश्यमान इंटरफ़ेस को बदतर बना देता है। हालांकि कॉपी-फाइल और कॉपी-ट्री के बीच स्विच करना मुश्किल नहीं है, लेकिन यह आवश्यक नहीं होना चाहिए। हो सकता है कि पायथन बग ट्रैकर पर copytreeएक एकल फ़ाइल की प्रतिलिपि बनाने के लिए एन्हांसमेंट अनुरोध दर्ज करें?
— बोबिन्स

जवाबों:


142

मैं आपको पहले कॉल करने का सुझाव देता हूं shutil.copytree, और यदि कोई अपवाद फेंक दिया जाता है, तो फिर से प्रयास करें shutil.copy।

import shutil, errno

def copyanything(src, dst):
    try:
        shutil.copytree(src, dst)
    except OSError as exc: # python >2.5
        if exc.errno == errno.ENOTDIR:
            shutil.copy(src, dst)
        else: raise

18
मुझे लगता है कि अगर यह एक अपवाद को पकड़ने के बजाय os.path.isdir (src) का उपयोग करके एक निर्देशिका है, तो यह केवल जाँच करने के लिए बहुत क्लीनर होगा। या क्या कोई विशेष कारण है कि इसके बजाय एक अपवाद का उपयोग करना चाहिए?
— पफकू

31
1) क्योंकि पायथन दुनिया में ईएएफपी (अनुमति की तुलना में माफी मांगना आसान है) को LBYL (आप लीप से पहले देखो) को प्राथमिकता दी जाती है। मैं आपको इसके बारे में लिंक प्रदान कर सकता हूं, अगर यह आपको नया लगता है। 2) पुस्तकालय समारोह पहले से ही अप्रत्यक्ष रूप से उसके लिए जाँच करता है, इसलिए चेक की प्रतिकृति क्यों? 3) कुछ भी नहीं shutil.copytreeभविष्य में दोनों मामलों में सुधार और प्रबंधन से फ़ंक्शन को रोकता है । 4) अपवाद पायथन में असाधारण नहीं हैं; उदाहरण के लिए स्टॉपइंटरेशन अपवाद को फेंकने से एक पुनरावृत्ति रुक ​​जाती है।
— ताज़ोत

2
खैर, इस मामले में अपवाद को संभालने में 6 लाइनें लगती हैं, जबकि प्रकार की जांच में 4 लाइनें लगती हैं। ज्यादा नहीं, लेकिन यह अंत में जोड़ता है। इसके अलावा, जैसा कि आप कहते हैं, नकल किसी दिन बहुत अच्छी तरह से फ़ाइलों का समर्थन कर सकती है। लेकिन यह बताना असंभव है कि कार्यान्वयन कैसा होगा। शायद यह कुछ परिस्थितियों में एक अपवाद फेंकता है जहां कॉपी काम करती है? उस स्थिति में मेरा कोड अचानक ही अतिरिक्त कार्यक्षमता के कारण काम करना बंद कर देगा। लेकिन आप शायद सही हैं, पायथन में बहुत कम अपवाद हैं, कुछ ऐसा जो मुझे बहुत कष्टप्रद लगता है, लेकिन यह शायद इसलिए है क्योंकि मुझे कभी इसकी आदत नहीं लगती है
— pafcu

5
वास्तव में अपवादों का इस मामले में एक स्पष्ट उद्देश्य लाभ है: यह पूरी तरह से संभव है (हालांकि अत्यधिक संभावना नहीं है) कि प्रकार चेक और कॉल के बीच सही फ़ंक्शन में बदलता है।
— 14 अक्टूबर को pafcu

2
मेरी व्यक्तिगत राय में, एक अपवाद को छोड़कर मुख्य कार्यक्षमता को जोड़ना बुरा व्यवहार है, इससे कोई फर्क नहीं पड़ता कि आप किस भाषा का उपयोग कर रहे हैं। यह एक जगह में कार्यक्षमता डालता है, जहां बहुत सारे डेवलपर्स खोज नहीं करेंगे। इसके अलावा, यदि आप एक टिप्पणी नहीं लिखते हैं, तो एक कम अनुभवी अजगर डेवलपर वास्तव में यह नहीं समझ पाएगा कि इस रिट्री का उद्देश्य क्या है। और अगर आपको यहां इस तरह की तुच्छ चीज़ के लिए टिप्पणी जोड़ने की आवश्यकता है, तो आपकी कोड शैली पर कुछ गलत है। अंत में, अगर / और लिखने से कोड पढ़ने में बहुत आसानी होगी।
— यह

7

Tzot के और gns के उत्तरों को जोड़ने के लिए , यहाँ फ़ाइलों और फ़ोल्डरों को पुनरावर्ती रूप से कॉपी करने का एक वैकल्पिक तरीका है। (अजगर 3.X)

import os, shutil

root_src_dir = r'C:\MyMusic'    #Path/Location of the source directory
root_dst_dir = 'D:MusicBackUp'  #Path to the destination folder

for src_dir, dirs, files in os.walk(root_src_dir):
    dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
    for file_ in files:
        src_file = os.path.join(src_dir, file_)
        dst_file = os.path.join(dst_dir, file_)
        if os.path.exists(dst_file):
            os.remove(dst_file)
        shutil.copy(src_file, dst_dir)

क्या यह आपकी पहली बार होना चाहिए और आपको पता नहीं है कि फ़ाइलों और फ़ोल्डरों की पुनरावृत्ति कैसे करें, मुझे उम्मीद है कि इससे मदद मिलेगी।


3

shutil.copyऔर shutil.copy2फ़ाइलों की प्रतिलिपि बना रहे हैं।

shutil.copytreeसभी फ़ाइलों और सभी सबफ़ोल्डरों के साथ एक फ़ोल्डर की प्रतिलिपि बनाता है। फ़ाइलों की प्रतिलिपि बनाने के लिए shutil.copytreeउपयोग कर रहा shutil.copy2है।

तो cp -rआपके द्वारा कहा जा रहा एनालॉग इसलिए है shutil.copytreeक्योंकि cp -rएक फ़ोल्डर और उसके फाइल / सबफ़ोल्डर जैसे लक्ष्यों और प्रतियों को कॉपी करता है shutil.copytree। बिना -r cpप्रतियां फ़ाइलें चाहते shutil.copyऔर shutil.copy2करते हैं।


1
मुझे नहीं लगता कि आपने प्रश्न को समझा। कोशिश करो shutil.copytree('C:\myfile.txt', 'C:\otherfile')। यह काम नहीं करता है। यही ओपी 7 साल पहले के बारे में पूछ रहा था।
— जीन-फ्रांकोइस कॉर्बेट

बेशक यह काम नहीं करता है। जैसे cp फोल्डर के साथ काम नहीं करता है। आपको एक विशेष विकल्प की आवश्यकता है। नकल से निपटने के लिए कॉपी और कॉपीराईट सबसे अच्छा तरीका है। यदि कॉपीराइट और लक्ष्य कर सकते हैं तो गलतियों को करना आसान होगा। आपको पता होना चाहिए कि आप लिनक्स और पायथन दोनों के साथ क्या लक्षित कर रहे हैं। वह कठिन। इसके अलावा किसी और ने यहाँ टिप्पणी की, लेकिन सवाल और जवाब देखकर जवाब का विरोध नहीं कर सका। सुरुचिपूर्ण तरीका यह जानना है कि आप क्या करना चाहते हैं और किसी भी नियंत्रण के बिना एक सार्वभौमिक प्रतिलिपि नहीं चाहते हैं।
— ग्राम

2

यूनिक्स cp'निर्देशिका और फ़ाइलों दोनों का समर्थन नहीं करता':

betelgeuse:tmp james$ cp source/ dest/
cp: source/ is a directory (not copied).

Cp को एक डायरेक्टरी को कॉपी करने के लिए, आपको मैन्युअल रूप से cp को बताना होगा कि वह '-r' फ्लैग का उपयोग करके एक डायरेक्टरी है।

हालांकि यहाँ कुछ डिस्कनेक्ट है - cp -rजब स्रोत के रूप में फ़ाइल नाम दिया गया तो खुशी से सिर्फ एक फ़ाइल की प्रतिलिपि होगी; नकल नहीं होगी।


2
docs.python.org/library/shutil.html में कोडपीट्री () के लिए कोड शामिल है, जो साधारण फाइलों, सिमिलिंक और निर्देशिकाओं को संभालने का प्रदर्शन करता है।
— जेम्स पोली

1
यह उत्तर प्रश्न को संबोधित नहीं करता है। यह एक टिप्पणी होनी चाहिए, एक जवाब नहीं।
— जीन-फ्रांकोइस कॉर्बेट

0

मुझे लगता है कि copy_tree वह है जो आप ढूंढ रहे हैं


-2

अजगर ने बंद कर दिया। मैंने एक काम किया है जो सही तरीके से काम करता है:

def copydirectorykut(src, dst):
    os.chdir(dst)
    list=os.listdir(src)
    nom= src+'.txt'
    fitx= open(nom, 'w')

    for item in list:
        fitx.write("%s\n" % item)
    fitx.close()

    f = open(nom,'r')
    for line in f.readlines():
        if "." in line:
            shutil.copy(src+'/'+line[:-1],dst+'/'+line[:-1])
        else:
            if not os.path.exists(dst+'/'+line[:-1]):
                os.makedirs(dst+'/'+line[:-1])
                copydirectorykut(src+'/'+line[:-1],dst+'/'+line[:-1])
            copydirectorykut(src+'/'+line[:-1],dst+'/'+line[:-1])
    f.close()
    os.remove(nom)
    os.chdir('..')

1
यह कोड काम के लिए व्यक्तिगत फाइल चेक (चेक ओवरराइटिंग इश्यू) के लिए अच्छा है, लेकिन बाइनरी फाइलों जैसे 'ज़िप' के लिए काम नहीं करेगा। लाइन रीड / राइट द्वारा लाइन के बजाय साधारण पायथन फाइल कॉपी का उपयोग क्यों नहीं किया जाता है?
— 15
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.