Tôi muốn mỗi phương thức lớp được gọi trong tập lệnh của tôi ghi lại thời gian cần thiết để hoàn thành phương thức đó. Cách tốt nhất/sạch nhất để thực hiện việc này mà không cần thêm ghi nhật ký vào mọi phương thức là gì?
Tôi có thể làm điều này bằng vũ lực, nhưng việc thêm cùng một bản soạn sẵn vào mọi phương pháp tôi viết có vẻ không đúng:
nhập ngày giờ dưới dạng dt
import logging
import sys
logger = ghi nhật ký.getLogger()
logging.basicConfig(level=logging.INFO)
lớp TestA(đối tượng):
phương thức def_one(tự):
Begin_at = dt.datetime.utcnow()
in "Phương thức được gọi_one"
end_at = dt.datetime.utcnow()
logger.info('{}.{} đã lấy {}'.format(
__tên__,
sys._getframe().f_code.co_name, # http://code.activestate.com/recipes/66062-determining-current-function-name/
kết thúc lúc - bắt đầu lúc,
))
phương thức def_two(tự):
Begin_at = dt.datetime.utcnow()
in "Phương thức được gọi_two"
end_at = dt.datetime.utcnow()
logger.info('{}.{} đã lấy {}'.format(
__tên__,
sys._getframe().f_code.co_name, # http://code.activestate.com/recipes/66062-determining-current-function-name/
kết thúc lúc - bắt đầu lúc,
))
lớp TestB(đối tượng):
phương thức def_ba (tự):
Begin_at = dt.datetime.utcnow()
in "Phương thức được gọi_ba"
end_at = dt.datetime.utcnow()
logger.info('{}.{} đã lấy {}'.format(
__tên__,
sys._getframe().f_code.co_name, # http://code.activestate.com/recipes/66062-determining-current-function-name/
kết thúc lúc - bắt đầu lúc,
))
t_a = TestA()
t_b = Kiểm traB()
t_a.method_one()
t_a.method_two()
t_a.method_one()
t_b.method_ba()
Chạy nó dẫn đến hành vi mong đợi:
Được gọi là phương thức_one
THÔNG TIN:test:__main__.method_one mất 0:00:00.000172
Được gọi là phương thức_two
THÔNG TIN:test:__main__.method_two mất 0:00:00.000006
Được gọi là phương thức_one
THÔNG TIN:kiểm tra:__main__.method_one mất 0:00:00.000005
Được gọi là phương thức_ba
THÔNG TIN:kiểm tra:__main__.method_ba mất 0:00:00.000005
Tôi nghĩ tôi nên sử dụng công cụ trang trí, nhưng tôi không có kinh nghiệm với những thứ này và lần thử đầu tiên của tôi đã thất bại:
phương thức def_logger(f):
Begin_at = dt.datetime.utcnow()
đầu ra = f()
end_at = dt.datetime.utcnow()
logger.info('{}.{} đã lấy {}'.format(
f.__tên__,
sys._getframe().f_code.co_name, # http://code.activestate.com/recipes/66062-determining-current-function-name/
kết thúc lúc - bắt đầu lúc,
))
đầu ra trở lại
lớp TestA(đối tượng):
phương thức def_one(tự):
in "Phương thức được gọi_one"
phương thức def_two(tự):
in "Phương thức được gọi_two"
lớp TestB(đối tượng):
phương thức def_ba (tự):
in "Phương thức được gọi_ba"
Tôi biết bằng cách nào đó tôi cần phải vượt qua "bản thân", nhưng không chắc chắn cách tốt nhất để thực hiện điều đó.
Traceback (most recent call last):
Tệp "test_logging.py", dòng 68, trong
lớp TestA(đối tượng):
Tệp "test_logging.py", dòng 69, trong TestA
@method_logger
Tệp "test_logging.py", dòng 59, trong Method_logger
đầu ra = f()
TypeError: Method_one() nhận chính xác 1 đối số (đã cho 0)
Làm cách nào tôi có thể tái tạo hành vi dự định của mình mà không cần trang trí mọi phương pháp mà tôi biết cách thực hiện? Nếu có cách nào tốt hơn để làm những gì tôi đang làm, vui lòng cho tôi biết, tôi rất muốn xem các ví dụ.
Sử dụng các chức năng định giờ và trang trí:
def timeit(phương thức):
định thời gian xác định (*args, **kw):
ts = time.time()
kết quả = phương thức(*args, **kw)
te = time.time()
delta = te - ts
giờ, số dư = divmod(delta, 3600)
phút, giây = divmod(dư lượng, 60)
logger.info('%s.%s đã lấy %02d:%02d:%02.6f',
phương thức.__module__,
phương thức.__name__,
int(giờ),
int(phút),
giây)
kết quả trả về
trả lại đúng thời gian
lớp TestA(đối tượng):
@timeit
phương thức def_one(tự):
in "Phương thức được gọi_one"
Tôi là một lập trình viên xuất sắc, rất giỏi!