2010-09-20 7 views
6

Có một cơ chế tương tự trong Python, với hiệu ứng set -x có trên bash không?Python có thể được thực hiện để tạo ra truy tìm tương tự như bash của bộ -x?

Dưới đây là một số ví dụ đầu ra từ bash trong chế độ này:

 
+ for src in cpfs.c log.c popcnt.c ssse3_popcount.c blkcache.c context.c types.c device.c 
++ my_mktemp blkcache.c.o 
+++ mktemp -t blkcache.c.o.2160.XXX 
++ p=/tmp/blkcache.c.o.2160.IKA 
++ test 0 -eq 0 
++ echo /tmp/blkcache.c.o.2160.IKA 
+ obj=/tmp/blkcache.c.o.2160.IKA 

Tôi nhận thức được những mô-đun Python trace, tuy nhiên sản lượng của nó có vẻ là cực kỳ dài dòng, và không phải trình độ cao như vậy của bash.

Trả lời

7

Có lẽ sử dụng sys.settrace:

Sử dụng traceit() để bật truy tìm, sử dụng traceit(False) để tắt truy tìm.

import sys 
import linecache 

def _traceit(frame, event, arg): 
    ''' 
    http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html 
    ''' 
    if event == "line": 
     lineno = frame.f_lineno 
     filename = frame.f_globals["__file__"] 
     if (filename.endswith(".pyc") or 
      filename.endswith(".pyo")): 
      filename = filename[:-1] 
     name = frame.f_globals["__name__"] 
     line = linecache.getline(filename, lineno) 
     print "%s # %s:%s" % (line.rstrip(), name, lineno,) 
    return _traceit 

def _passit(frame, event, arg): 
    return _passit 

def traceit(on=True): 
    if on: sys.settrace(_traceit) 
    else: sys.settrace(_passit) 

def mktemp(src): 
    pass 

def my_mktemp(src): 
    mktemp(src) 
    p=src 

traceit() 
for src in ('cpfs.c','log.c',): 
    my_mktemp(src) 
traceit(False) 

mang

mktemp(src) # __main__:33 
pass # __main__:30 
p=src # __main__:34 
mktemp(src) # __main__:33 
pass # __main__:30 
p=src # __main__:34 
if on: sys.settrace(_traceit) # __main__:26 
else: sys.settrace(_passit) # __main__:27 
+0

Nice! Tôi chưa bao giờ thấy thứ này! – daitangio

+0

Xin chào, tôi sẽ thử ngay. –

0

Bạn nên cố gắng thiết lập mô-đun theo dõi để có mức chi tiết cao hơn. Bạn cần chính xác những gì?

1

Để dõi các cuộc gọi cụ thể, bạn có thể quấn mỗi chức năng thú vị với logger của riêng bạn. Điều này dẫn đến các đối số được mở rộng đến các giá trị của chúng hơn là chỉ các tên đối số trong đầu ra.

Chức năng phải được chuyển thành chuỗi để ngăn chặn các sự cố trong đó mô-đun chuyển hướng đến các mô-đun khác, như os.path/posixpath. Tôi không nghĩ rằng bạn có thể trích xuất tên mô-đun đúng để vá từ chỉ đối tượng hàm. đang

Wrapping:

import importlib 

def wrapper(ffull, f): 
    def logger(*args, **kwargs): 
     print "TRACE: %s (%s, %s)" % (ffull, args, kwargs) 
     return f(*args, **kwargs) 
    return logger 

def log_execution(ffull): 
    parts = ffull.split('.') 
    mname = '.'.join(parts[:-1]) 
    fname = parts[-1] 
    m = importlib.import_module(mname) 
    f = getattr(m, fname) 
    setattr(m, fname, wrapper(ffull, f)) 

Cách sử dụng:

for f in ['os.path.join', 'os.listdir', 'sys.exit']: 
    log_execution(f) 

p = os.path.join('/usr', 'bin') 
os.listdir(p) 
sys.exit(0) 

.... 

% ./a.py 
TRACE: os.path.join (('/usr', 'bin'), {}) 
TRACE: os.listdir (('/usr/bin',), {}) 
TRACE: sys.exit ((0,), {})