2013-06-13 13 views
5

के तहत shutil.copystat (file1, file2) को कॉल करने के बाद फ़ाइल संशोधन समय बराबर नहीं है, मैं पाइथन 2.7.5 के साथ निम्न कोड चलाता हूं। Windows के तहत:विंडोज़

import os, shutil, stat, time 

with open('test.txt', 'w') as f: pass # create an arbitrary file 
shutil.copy('test.txt', 'test2.txt') # copy it 
shutil.copystat('test.txt', 'test2.txt') # copy its stats, too 

t1 = os.lstat('test.txt').st_mtime # get the time of last modification for both files 
t2 = os.lstat('test2.txt').st_mtime 

print t1 # prints something like: 1371123658.54 
print t2 # prints the same string, as expected: 1371123658.54 
print t1 == t2 # prints False! Why?! 

मैं दोनों टाइम स्टांप (= तैरता) बराबर होने की उम्मीद है (जैसा कि उनके स्ट्रिंग अभ्यावेदन सुझाव है), तो क्यों t1 == t2False को मूल्यांकन करता है?

इसके अलावा, मैं दो अलग फाइलों से timestamps os.lstat के ज़रिये पुनः प्राप्त की तुलना के बिना कम कोड, अर्थात् इस व्यवहार पुन: पेश करने में असमर्थ था। मैं महसूस कर रही है, मैं कुछ यहाँ तुच्छ याद आ रही है ...


संपादित करें: आगे के परीक्षण मैंने देखा के बाद, कि यह एक समय में एक बार प्रिंट True करता है, लेकिन नहीं अधिक बार एक बार से हर 10 रन।


संपादित करें 2: larsmans द्वारा सुझाव दिया गया है:

print ("%.7f" % t1) # prints e.g. 1371126279.1365688 
print ("%.7f" % t2) # prints e.g. 1371126279.1365681 

यह दो नए सवाल उठे:

  1. क्यों timestamps shutil.copystat बुला के बाद बराबर नहीं कर रहे हैं?
  2. print राउंड डिफ़ॉल्ट रूप से तैरते हैं ?!
+0

डेबियन लिनक्स पर पुन: पेश नहीं किया जा सकता है। "छोटा प्रिंट" अलग है या नहीं, यह देखने के लिए 'प्रिंट ("%। 7f"% t1) 'और' (t1 - t2) <1e-4' आज़माएं। –

+0

यह देखने के लिए कि प्रिंट राउंड डिफ़ॉल्ट रूप से क्यों तैरते हैं, इसे आज़माएं: 'x = 10.1 (newline) प्रिंट ("% .20f "% x)'। यह आपके विचार से कुछ और प्रिंट करेगा। यह सामान्य है क्योंकि फ़्लोटिंग पॉइंट मान सभी आंशिक मानों का बिल्कुल प्रतिनिधित्व नहीं कर सकते हैं। हालांकि मुझे शटल समस्या के बारे में कोई जानकारी नहीं है। –

+0

मुझे बाइनरी प्रतिनिधित्व के बारे में पता है, लेकिन यहां मामला अलग है: हमारे पास '10.0 99 999' मान के साथ एक फ्लोट है और यह' 10.1' प्रिंट करता है हालांकि हमने '% .2f' जैसे प्रारूप निर्दिष्ट नहीं किए हैं - इसलिए ऐसा लगता है कि ऐसा लगता है प्रभाव में अंतर्निहित दौर, जिसे मैं नहीं जानता था और मैंने पहले कभी नहीं देखा ... –

उत्तर

5

समस्या के लिए copystat कॉल के दौरान विभिन्न स्वरूपों के बीच रूपांतरण के साथ है। ऐसा इसलिए है क्योंकि विंडोज़ फ़ाइल समय को एक निश्चित-बिंदु दशमलव प्रारूप में संग्रहीत करता है, जबकि पायथन उन्हें फ़्लोटिंग-पॉइंट बाइनरी प्रारूप में संग्रहीत करता है। तो हर बार दो प्रारूपों के बीच एक रूपांतरण होता है, कुछ सटीकता खो जाती है।

  1. os.stat को एक कॉल पायथन के फ्लोटिंग प्वाइंट प्रारूप करने के लिए Windows प्रारूप धर्मान्तरित: copystat कॉल के दौरान। कुछ सटीकता खो जाती है।
  2. os.utime फ़ाइल समय को अद्यतन करने के लिए कहा जाता है। यह इसे विंडोज प्रारूप में बदल देता है। कुछ सटीकता फिर से खो जाती है, और फ़ाइल का समय जरूरी नहीं है कि पहली फ़ाइल के समान हो।

जब आप os.lstat स्वयं को कॉल करते हैं, तो तीसरा गलत रूपांतरण किया जाता है। इन रूपांतरणों के कारण, फ़ाइल का समय बिल्कुल वही नहीं है।

ध्यान दें कि सही समय आप यहां सेट, संकल्प के आधार पर बाद में एक स्टेट() कॉल द्वारा वापस नहीं आ सकते हैं जिसके साथ आपके ऑपरेटिंग सिस्टम के रिकॉर्ड का उपयोग और संशोधन बार

:

documentation for os.utime में यह उल्लेख है str(f) या के साथ एक स्ट्रिंग के लिए एक फ़्लोटिंग-बिंदु मान परिवर्तित:


अपने दूसरे प्रश्न के संबंध में (क्यों print दोनों के लिए समान मूल्यों को दिखाने के लिए दिखाई देता है) print f मूल्य के चारों ओर होगा। विभिन्न फ़्लोटिंग-पॉइंट मानों के लिए अद्वितीय होने की गारंटी प्राप्त करने के लिए, इसके बजाय print repr(f) का उपयोग करें।

-1

चल बिन्दु में समय अंतर मुद्रण का प्रयास करें: print float.hex(t1 - t2)

परिणाम:

0x1.0000000000000p-22 
0x1.8000000000000p-21 
0x0.0p+0 
0x1.0000000000000p-20 

मेरे 2cents अनुमान: उत्पादन में भिन्नता चल बिन्दु प्रतिनिधित्व पूर्वाग्रह और त्रुटि गोलाई से आता है। वैसे भी, आपको दो फ्लोट की तुलना करते समय हमेशा एक ईपीएसलॉन मानों का उपयोग करना चाहिए।

संपादित करें: यह Python bug देखें।

यह एक सिस्टम सीमा है। अंतर्निहित फ़ाइल सिस्टम फ़ाइल टिकटों के लिए नैनोसेकंद रिज़ॉल्यूशन का समर्थन करता है, और स्टेट (2) उन्हें रिपोर्टिंग का भी समर्थन करता है। हालांकि, utimes (2) केवल उन्हें सेट करते समय microsecond संकल्प का समर्थन करता है।

आपको दो फ्लोट की तुलना करते समय सबसे अच्छा माइक्रोक्रॉन्ड रिज़ॉल्यूशन का उपयोग करना होगा।

+1

हाँ, और अधिक परेशान करने वाला यह है कि टी 1 टी 2 से बड़ा है, जबकि इसके विपरीत (टेक्स्ट 2 टेक्स्ट 1 से अधिक हालिया है) – lucasg

+0

वह बग रिपोर्ट एक लिनक्स प्रणाली के लिए है। पायथन का विंडोज कार्यान्वयन 'utimes' का उपयोग नहीं करता है, इसलिए ऐसी कोई माइक्रोसेकंड सीमा नहीं है। – interjay

+0

GetFileTime (http://msdn.microsoft.com/en-us/library/windows/desktop/ms724320 (v = vs.85) .aspx) में 10 मिलीसेकंद रिज़ॉल्यूशन है, इसलिए मुझे लगता है कि विंडोज़ पर शटल बेहतर नहीं कर सकता है। (मैंने पाइथन कोड में देखा है और lstat winapi GetFileAttributesExW ) – lucasg

0
from decimal import * 
print Decimal(t1) 
print Decimal(t2) 

उपयोग दौर() t1 और t2