Làm thế nào để sử dụng thanh tra để lấy thông tin của người gọi từ callee trong Python?


80

Tôi cần lấy thông tin người gọi (tệp / dòng gì) từ callee. Tôi biết được rằng tôi có thể sử dụng mô-đun inpect cho mục đích đó, nhưng không chính xác như thế nào.

Làm thế nào để có được những thông tin đó với thanh tra? Hoặc có cách nào khác để lấy thông tin?

import inspect

print __file__
c=inspect.currentframe()
print c.f_lineno

def hello():
    print inspect.stack
    ?? what file called me in what line?

hello()

Câu trả lời:


99

Khung của người gọi cao hơn một khung so với khung hiện tại. Bạn có thể sử dụng inspect.currentframe().f_backđể tìm khung của người gọi. Sau đó, sử dụng verify.getframeinfo để lấy tên tệp và số dòng của người gọi.

import inspect

def hello():
    previous_frame = inspect.currentframe().f_back
    (filename, line_number, 
     function_name, lines, index) = inspect.getframeinfo(previous_frame)
    return (filename, line_number, function_name, lines, index)

print(hello())

# ('/home/unutbu/pybin/test.py', 10, '<module>', ['hello()\n'], 0)

7
@prosseek: Để nhận được người gọi của người gọi, chỉ cần thay đổi chỉ mục [1]thành [2]. ( inspect.getouterframestrả về danh sách các khung ...). Python được tổ chức rất đẹp.
unutbu 14/09/10

3
Bạn cũng có thể sử dụng checks.currentframe (). F_back.
yoyo

Điều này dường như không cung cấp cách để lấy đường dẫn đầy đủ của tên tệp.
Jason S

2
@JasonS: "tên tệp trong khung ngăn xếp có liên quan đến thư mục khởi động của ứng dụng".
unutbu

4
Mẫu mã này hoạt động nhưng hoạt động khá kém. Nếu bạn chỉ quan tâm đến một khung duy nhất và không phải toàn bộ stack trace, bạn có thể lấy khung trước và kiểm tra nó cho các thông tin khung: filename, line_number, clsname, lines, index = inspect.getframeinfo(sys._getframe(1))
Mouscellaneous

47

Tôi sẽ đề nghị sử dụng inspect.stackthay thế:

import inspect

def hello():
    frame,filename,line_number,function_name,lines,index = inspect.stack()[1]
    print(frame,filename,line_number,function_name,lines,index)
hello()

Nó tốt hơn getouterframesnhư thế nào so với việc sử dụng theo gợi ý của @unutbu?
ixe013

8
Nó nhỏ gọn hơn và phản ánh ý định tốt hơn.
Dmitry K.

Lưu ý rằng getouterframes(currentframe())stack()tương đương với github.com/python/cpython/blob/master/Lib/inspect.py#L1442
ubershmekel

1
Một lý do khác khi sử dụng stack () là tốt là nó chỉ ra cách dễ dàng lấy các khung khác. Nếu chẳng hạn. Hàm hello () của bạn được gọi bởi một hàm khác trước tiên, bạn có thể cập nhật nó để quay lại hai cấp.
Charles Plager


-5

Nếu trình gọi là tệp chính, chỉ cần sử dụng sys.argv [0]

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.