2015-09-15 18 views
7

Tôi muốn xác định chức năng nhật ký được gọi bằng một tin nhắn theo sau bởi một hoặc nhiều biến được in ra. Vì vậy, giống như sau:Làm cách nào để in các đối số biến với tên từ ngăn xếp trước?

log("Oh no, error.", x, d) 

log sẽ được xác định sorta thích:

def log(msg, *arg): 
    # Loop through arg, printing caller's variable's name and value. 

này sẽ đăng nhập vào một tập tin như sau:

Oh no, error. 
    x = 5 
    d = { foo: "Foo", goo: "Goo" } 

này có thể được thực hiện tại tất cả ? Tôi có thể in người dân địa phương và các đối số bằng cách sử dụng kiểm tra, nhưng tôi không biết nếu tôi có thể lặp qua các giá trị trong khung hiện tại, sử dụng tên biến của một khung trước đó. (locals trong inspect.getargvalues(previousFrame) có tên, nhưng rất nhiều tên khác nữa.)

+1

Làm thế nào để bạn xác định duy nhất tên biến? Điều gì sẽ xảy ra nếu người gọi có 'y' trong không gian tên và giá trị của nó cũng xảy ra là' 5'? Điều gì sẽ xảy ra nếu người gọi chuyển một cái gì đó như 'd ['foo']'? Bạn có cần phải recurse sâu vào các đối tượng trong không gian tên của người gọi không? Điều gì xảy ra nếu chúng vượt qua kết quả của một cuộc gọi hàm? 'log ('message', x.bar())'? Có rất nhiều trường hợp khá khó giải quyết ở đây ... mặc dù bạn có thể kiểm tra ngăn xếp và in ra _all_ các biến cục bộ của người gọi. – mgilson

+0

* thở dài * Vâng, tôi đoán bạn đúng mgilson. Vậy tôi nên làm gì đây? Tôi có phải xóa bài đăng này không? Hoặc có lẽ đó là suy nghĩ mơ hồ của tôi, tôi chỉ muốn có một chức năng đăng nhập ghi nhật ký các biến mà tôi đưa ra. Điều này không thể được thực hiện ở tất cả? Vì vậy, nếu họ vượt qua nó 5, nó in 5 = 5. nếu họ vượt qua nó y, nó in y = 5. Nếu họ vượt qua nó một đối tượng, nó in object = str (đối tượng). – Bitdiot

+0

@Bitdiot, tại sao? Nó không được viết xấu hoặc được tổ chức kém. Và đối với cá nhân tôi câu hỏi là thú vị – ForceBru

Trả lời

4

Tôi nghĩ rằng bạn có thể sử dụng một cái gì đó như thế này:

nét

def log(msg, **kwargs): 
    print(msg) 
    for key, value in kwargs.items(): 
     print('{0} = {1}'.format(key,value)) 

định nghĩa (nếu trật tự là điều bắt buộc)

def log(msg, **kwargs): 
    print(msg) 
    for key, value in sorted(kwargs.items()): 
     print('{0} = {1}'.format(key,value)) 

sử dụng

msg='Oh no, error' 
log(msg, x=5, y=6) 

đầu ra

Oh no, error 
y = 6 
x = 5 
+2

Điều này là tốt, vì nó không sử dụng bất kỳ ma thuật đen nào. Ngoài ra [rõ ràng là tốt hơn là ngầm] (https://www.python.org/dev/peps/pep-0020/). –

+2

Lưu ý rằng thứ tự của các đối số không nhất thiết là những gì bạn mong đợi ... http://stackoverflow.com/questions/8977594/in-python-what-determines-the-order-while-iterating-through-kwargs –

+0

Bạn nói đúng, tôi đã không đưa vào tài khoản ở đây, tôi nên đã chỉ ra một thực tế là từ điển không có thứ tự. Tôi đã chỉnh sửa câu trả lời. – jlnabais

1

Đó có thể là rất bẩn và không thể làm việc bất cứ lúc nào (nó làm như vậy trên máy tính của tôi), nhưng có vẻ như để làm các trick.

Hơn nữa, nó không cần tất cả các thủ thuật **keargs này. Bạn chỉ cần gọi log('Message',as,many,args,as,you,want) và đó là tất cả.

import inspect, gc 

def log(msg,*args): 
    #This gets the source code line that has to do with args 
    #I mean, that calls log 
    code=''.join(inspect.getframeinfo(gc.get_referrers(args)[0].f_back).code_context).strip() 
    #get the arguments (except msg) 
    c=code.split('log')[1].strip() 
    c=c.replace('(','').replace(')','') 
    c=c.split(',')[1:] 
    if c[-1].endswith(';'): 
     c[-1]=c[-1].replace(';','') 

    for x in xrange(0,len(c)): 
     print c[x],'=',args[x] 


a=5; b='hello' 

print 'test' 

log('hello',a,b); 

print 'hello' 

Ngay cả khi log được chạy từ một chức năng khác, OK.

+0

Tôi đã thử điều này. Thực sự tiện lợi tìm kiếm mã, nhưng nếu nhật ký là trên nhiều dòng, có vẻ như chuyến đi lên.Tôi vẫn thích nó, nhưng tôi nghĩ tôi đang nghiêng về phía giải pháp key = val. – Bitdiot

Các vấn đề liên quan