2011-11-08 9 views
6

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

>>> 5 * 7 
35 
>>> print("Hello, world!") 
Hello, world! 
>>> "Hello, world!" 
'Hello, world!' 

मैं एक लॉग फ़ाइल में निम्नलिखित देखना चाहते हैं:

> 5 * 7 
35 
> print("Hello, world!") 
Hello, world! 
> "Hello, world!" 
'Hello, world!' 

स्वरूपण महत्वपूर्ण नहीं है; महत्वपूर्ण बात यह है कि मैं सत्र के दौरान इंटरैक्टिव घटनाओं को ट्रिगर करने के लिए कुंजी शब्दों के लिए फ़ाइल खोज सकता हूं।

मैं अब तक क्या सीखा है यह पूरा करने की कोशिश कर रहा:

पायथन के code मॉड्यूल मुझे एक InteractiveConsole वस्तु बनाने के लिए अनुमति देता है, raw_input विधि जिनमें से मैं, तो जैसे एक फाइल करने के लिए लॉग इन करने को फिर से परिभाषित कर सकते हैं:

import code 
class LoggedConsole(code.InteractiveConsole): 
    def __init__(self, locals): 
    super(LoggedConsole, self).__init__(locals) 
    self.file = open('consolelog.dat', 'a') 

    def __del__(self): 
    self.file.close() 

    def raw_input(self, prompt=""): 
    data = input(prompt) 
    self.file.write(data+'\n') 
    return data 

इसके अलावा, InteractiveConsole का उपयोग करता है एक अंतर्निहित write विधि त्रुटियों, जो मैं करने के लिए फिर से परिभाषित कर सकते हैं प्रवेश करने के लिए:

def write(self, data): 
    sys.stderr.write(data) 
    self.file.write(data+'\n') 

मैं भी सीखा है कि निम्नलिखित स्निपेट सभी stdout प्रवेश करेंगे:

class Tee(object): 
    def __init__(self): 
    self.file = open('consolelog.dat', 'a') 
    self.stdout = sys.stdout 

    def __del__(self): 
    sys.stdout = self.stdout 
    self.file.close() 

    def write(self, data): 
    self.file.write(data) 
    self.stdout.write(data) 

sys.stdout = Tee() 

मेरे (टूट) यह सब एक साथ फिर एक LoggedConsole वस्तु बनाने के लिए था लाने के लिए, और स्थानीय लोगों में यह Tee पारित करने के लिए प्रयास करते हैं।

console = LoggedConsole(locals={sys.stdout:LoggedExec()}) 
console.interact() 

(मैं पारित नहीं किया गया है स्थानीय लोगों से पहले, तो शायद मैं इसे गलत तरीके से यहाँ कर रहा हूँ, लेकिन मैं एक त्रुटि प्राप्त नहीं है।)

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

इसके अलावा, क्या सत्र के दौरान ऐसा होने का कोई तरीका है? सत्र बंद होने के बाद वर्तमान में सभी लॉगिंग होती है।

आपके समय के लिए धन्यवाद, पाठ की दीवार के लिए खेद है।

संपादित करें: मैं पोर्टेबिलिटी उद्देश्यों के लिए मानक पायथन दुभाषिया में इसे पूरा करने में सक्षम होना चाहता हूं।

संपादन 2: जैम का स्निपेट मुझे जो भी चाहिए, उसे लॉग इन करने के लिए बहुत अच्छा काम करता है। किसी भी तरह से, हालांकि, मैं इसे वास्तविक समय में कर सकता हूं, सत्र को बंद करने की प्रतीक्षा करने के बजाय?

संपादित 3: इसे समझ लिया :)। अंतिम, काम टुकड़ा:

import code 
import sys 

class Tee(object): 
    def __init__(self, log_fname, mode='a'): 
    self.log = open(log_fname, mode) 

    def __del__(self): 
    # Restore sin, so, se 
    sys.stdout = sys.__stdout__ 
    sys.stdir = sys.__stdin__ 
    sys.stderr = sys.__stderr__ 
    self.log.close() 

    def write(self, data): 
    self.log.write(data) 
    self.log.flush() 
    sys.__stdout__.write(data) 
    sys.__stdout__.flush() 

    def readline(self): 
    s = sys.__stdin__.readline() 
    sys.__stdin__.flush() 
    self.log.write(s) 
    self.log.flush() 
    return s 

    def flush(foo): 
    return 

sys.stdout = sys.stderr = sys.stdin = Tee('consolelog.dat', 'w') 

console = code.InteractiveConsole() 
console.interact() 
+0

बीटीडब्ल्यू सुनिश्चित नहीं है कि आपका उपयोग केस क्या है लेकिन 'ipython notebook' एक इंटरैक्टिव वर्कफ़्लो के लिए एक बढ़िया इसके अलावा है, यदि आपने इसे अभी तक नहीं देखा है। – Kos

उत्तर

7

मैं केवल python2.7 में यह परीक्षण किया है। मेरे पास 3 आसान नहीं है।

import code 
import sys 

class Tee(object): 

    def __init__(self, log_fname, mode='a'): 
    self.log = open(log_fname, mode) 

    def __del__(self): 
    # Restore sin, so, se 
    sys.stdout = sys.__stdout__ 
    sys.stdir = sys.__stdin__ 
    sys.stderr = sys.__stderr__ 
    self.log.close() 

    def write(self, data): 
    self.log.write(data) 
    sys.__stdout__.write(data) 

    def readline(self): 
    s = sys.__stdin__.readline() 
    self.log.write(s) 
    return s 

# Tie the ins and outs to Tee. 
sys.stdout = sys.stderr = sys.stdin = Tee('consolelog.dat', 'w') 

console = code.InteractiveConsole() 
console.interact() 
+0

यह बहुत अच्छी तरह से काम करता है। क्या आपको कोई आइडिया है कि मैं इसे वास्तविक समय में कैसे लॉग कर सकता हूं? यानी सत्र तक लिखने के लिए बंद होने तक प्रतीक्षा न करें? मैंने कहीं पढ़ा है कि 'sys.stdout.flush()', आदि के लिए एक कॉल यह करेगा, लेकिन मुझे यह लागू करने के बारे में थोड़ा अनिश्चितता है कि कैसे कार्यान्वित किया जाए। अब तक आपकी मदद के लिए धन्यवाद! –

+1

इसे समझ लिया। आपको लॉग फ़ाइल के लिए, और stdout/वस्तुओं में दोनों के लिए 'flush()' दोनों को कॉल की आवश्यकता है। सही दिशा में मुझे धक्का देने के लिए धन्यवाद! –

+0

खुशी है कि यह आपकी मदद की। आपको केवल लॉग फ्लश करने की आवश्यकता होनी चाहिए। stdout/stderr flush करने का कोई कारण नहीं है। याद रखें, लॉग वास्तव में फ़ाइल को लिखने वाली एकमात्र चीज़ है, इसलिए इसे फ़्लश करना पर्याप्त होना चाहिए। – jaime

5

IPython पर एक नज़र डालें (यह अपने आप उपयोग नहीं किया है)।http://ipython.org/ipython-doc/dev/interactive/reference.html#session-logging-and-restoring

+0

आह, मेरा उल्लेख है (लेकिन भूल गया) कि मैं मानक पायथन दुभाषिया का उपयोग करना पसंद करूंगा। मैं iPython पर वापस गिरना समाप्त कर सकता हूं, लेकिन मैं इसे बिना पहले पूरा करने की कोशिश करना चाहता हूं। –

3

डौग Hellmann द्वारा this Virtualenv article देखें, एक iPython सत्र को लॉग करने के लिए कैसे दिखा:: यहाँ डॉक्स में एक वर्ग है कि विशेष रुचि का हो सकता है

आप इस तरह से इंटरैक्टिव प्रॉम्प्ट पर काम कर सही हैं, तो , लेकिन आप अपने सत्र को बंद करने के बाद भविष्य के संदर्भ के लिए क्या करना चाहते हैं, रिकॉर्ड करना चाहते हैं, आप फ़ाइल में सत्र लिखने के लिए आईपीथन की लॉगिंग सुविधा का उपयोग कर सकते हैं। लॉग को सक्रिय करने के लिए, नियंत्रण कमांड %logstart का उपयोग करें, जैसा कि लिस्टिंग 5 में दिखाया गया है। आउटपुट फ़ाइल एक पायथन स्रोत फ़ाइल है, इसलिए इसे साफ़ करना आसान है और इसे प्रयोग करने के दौरान इसे "असली" मॉड्यूल में बदलना आसान है।

In [6]: %logstart 
Activating auto-logging. Current session state plus future input saved. 
Filename  : ipython_log.py 
Mode   : rotate 
Output logging : False 
Raw input log : False 
Timestamping : False 
State   : active 

In [7]: a = 5 

In [8]: b = 6 

In [9]: c = a * b 

In [10]: c 

Out[10]: 30 

In [11]: d = [ a, b, c] 

In [12]: d 

Out[12]: [5, 6, 30] 

In [13]: %logstop 
+0

संदर्भ के लिए धन्यवाद! हालांकि, मैं इस काम को मानक दुभाषिया में बनाना चाहता हूं। मेरा लक्ष्य यहां पाइथन मूल बातें (और स्वयं को रास्ते में पढ़ाने के लिए) के लिए एक इंटरैक्टिव ट्यूटोरियल बनाना है, और मैं इसे दोस्तों के लाभ के लिए पोर्टेबल बनाना चाहता हूं जो इसका उपयोग कर सकते हैं। –

2

आप बस, कोशिश यूनिक्स स्क्रिप्ट आदेश का उपयोग कर सकते हैं:

Script started on Sat Dec 14 11:18:41 2013 
python 
>> print('hi') 
hi 
>> exit() 
exit 

Script done on Sat Dec 14 11:18:59 2013 
0
:, यह कुछ इस तरह दिखेगा

script -a filename.txt 
python 
>> print("hi") 
hi 
>> exit() 
exit 

filename.txt सब कुछ आपको लगता है कि सत्र पर किया था रिकॉर्ड करेगा

आप मेरे लॉगिंग टूल को आजमा सकते हैं और उपयोग कर सकते हैं। यह अभी तक सही नहीं है लेकिन यह मेरी समस्या हल करता है, जो आपके जैसा लगता है।

https://github.com/hholst80/loginteractive

यह पाइप stdin.txt (या $ STDIN) stdout के लिए करने के लिए LD_PRELOAD का उपयोग करके काम करता है। यह अजगर और ऑक्टेट के लिए काम करता है, हालांकि मैंने इसका परीक्षण नहीं किया है कि अभी तक बहुत कुछ है।

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