Giả sử tôi đã viết một trình trang trí làm một cái gì đó rất chung chung. Ví dụ: nó có thể chuyển đổi tất cả các đối số thành một kiểu cụ thể, thực hiện ghi nhật ký, triển khai ghi nhớ, v.v.
Đây là một ví dụ:
def args_as_ints(f):
def g(*args, **kwargs):
args = [int(x) for x in args]
kwargs = dict((k, int(v)) for k, v in kwargs.items())
return f(*args, **kwargs)
return g
@args_as_ints
def funny_function(x, y, z=3):
"""Computes x*y + 2*z"""
return x*y + 2*z
>>> funny_function("3", 4.0, z="5")
22
Mọi thứ tốt cho đến nay. Tuy nhiên, có một vấn đề. Chức năng được trang trí không giữ lại tài liệu về chức năng ban đầu:
>>> help(funny_function)
Help on function g in module __main__:
g(*args, **kwargs)
May mắn thay, có một cách giải quyết:
def args_as_ints(f):
def g(*args, **kwargs):
args = [int(x) for x in args]
kwargs = dict((k, int(v)) for k, v in kwargs.items())
return f(*args, **kwargs)
g.__name__ = f.__name__
g.__doc__ = f.__doc__
return g
@args_as_ints
def funny_function(x, y, z=3):
"""Computes x*y + 2*z"""
return x*y + 2*z
Lần này, tên hàm và tài liệu chính xác:
>>> help(funny_function)
Help on function funny_function in module __main__:
funny_function(*args, **kwargs)
Computes x*y + 2*z
Nhưng vẫn còn một vấn đề: chữ ký hàm bị sai. Thông tin "* args, ** kwargs" là vô ích.
Để làm gì? Tôi có thể nghĩ ra hai cách giải quyết đơn giản nhưng thiếu sót:
1 - Bao gồm chữ ký chính xác trong chuỗi tài liệu:
def funny_function(x, y, z=3):
"""funny_function(x, y, z=3) -- computes x*y + 2*z"""
return x*y + 2*z
Điều này thật tệ vì sự trùng lặp. Chữ ký sẽ vẫn không được hiển thị chính xác trong tài liệu được tạo tự động. Thật dễ dàng để cập nhật hàm và quên việc thay đổi chuỗi tài liệu hoặc mắc lỗi đánh máy. [ Và vâng, tôi biết thực tế là docstring đã sao chép nội dung hàm. Hãy bỏ qua điều này; fun_ Chức năng chỉ là một ví dụ ngẫu nhiên.]
2 - Không sử dụng trình trang trí hoặc sử dụng trình trang trí có mục đích đặc biệt cho mọi chữ ký cụ thể:
def funny_functions_decorator(f):
def g(x, y, z=3):
return f(int(x), int(y), z=int(z))
g.__name__ = f.__name__
g.__doc__ = f.__doc__
return g
Điều này hoạt động tốt đối với một tập hợp các hàm có chữ ký giống hệt nhau, nhưng nói chung nó vô dụng. Như tôi đã nói ở phần đầu, tôi muốn có thể sử dụng các bộ trang trí hoàn toàn chung chung.
Tôi đang tìm kiếm một giải pháp hoàn toàn chung chung và tự động.
Vậy câu hỏi đặt ra là: có cách nào để chỉnh sửa chữ ký hàm được trang trí sau khi nó đã được tạo không?
Nếu không, tôi có thể viết trình trang trí trích xuất chữ ký hàm và sử dụng thông tin đó thay vì "* kwargs, ** kwargs" khi xây dựng hàm được trang trí không? Làm cách nào để trích xuất thông tin đó? Tôi nên xây dựng hàm được trang trí như thế nào - với hàm executive?
Bất kỳ cách tiếp cận nào khác?
inspect.Signature
được thêm vào việc xử lý các chức năng được trang trí.