Tôi đang cố gắng viết một trình trang trí giữ nguyên các đối số của các hàm mà nó trang trí. Động cơ để làm điều này là viết một trang trí tương tác độc đáo với pytest.fixtures
.Python tạo các đối số chức năng bảo quản trang trí
Giả sử chúng tôi có chức năng foo
. Phải có một đối số a
.
def foo(a):
pass
Nếu chúng ta có được spec đối số của foo
>>> inspect.getargspec(foo)
ArgSpec(args=['a'], varargs=None, keywords=None, defaults=None)
Chúng tôi thường muốn tạo một trang trí nơi wrapper
chức năng vượt qua tất cả các đối số của nó đúng nguyên văn để các wrapped
chức năng. Cách rõ ràng nhất để thực hiện việc này là sử dụng *args
và **kwargs
.
def identity_decorator(wrapped):
def wrapper(*args, **kwargs):
return wrapped(*args, **kwargs)
return wrapper
def identity_decorator(wrapped):
def wrapper(*args, **kwargs):
return wrapped(*args, **kwargs)
return wrapper
@identity_decorator
def foo(a):
pass
này, không đáng ngạc nhiên, tạo ra một chức năng với một spec lập luận phản ánh *args
và **kwargs
.
>>> inspect.getargspec(foo)
ArgSpec(args=[], varargs='args', keywords='kwargs', defaults=None)
Có cách nào thay đổi thông số đối số để khớp với hàm được bao bọc hoặc tạo hàm có thông số đối số phù hợp ban đầu không?
Tôi nghĩ rằng trong các phiên bản gần đây Python, 'functools.wraps' làm điều gì đó để làm cho 'inspect.getargspec' và' kiểm tra .signature' báo cáo chữ ký của hàm được bọc, nhưng nó không thay đổi chữ ký thực của trình bao bọc. Thư viện bên thứ ba ['decorator'] (https://pypi.python.org/pypi/decorator) cung cấp chức năng trang trí bảo quản chữ ký thực thông qua các phương tiện mà tôi chưa bao giờ nhìn sâu vào, có thể liên quan đến một số thứ như viết lại bytecode. Tôi chưa bao giờ sử dụng nó. – user2357112
Có thể kiểm tra nội dung nào đó như http://stackoverflow.com/questions/3729378/how-can-i-programmatically-change-the-argspec-of-a-function-in-a-python-decorato – Nf4r