Tôi cần một cái gì đó cho cùng mục đích, nhưng không có câu trả lời hiện có nào bao gồm tất cả các trường hợp tôi đã thử nghiệm. Câu trả lời của Nadia là câu trả lời gần nhất với những gì tôi đang tìm kiếm, vì vậy tôi bắt đầu với mã của cô ấy làm cơ sở.
Trình trang trí bên dưới hoạt động với tất cả các kết hợp hợp lệ của các đối số:
Positional __init__(self, a, b )
Keyword __init__(self, a=None, b=None )
Positional + Keyword __init__(self, a, b, c=None, d=None)
Variable Positional __init__(self, *a )
Variable Positional + Keyword __init__(self, *a, b=None )
Variable Positional + Variable Keyword __init__(self, *a, **kwargs )
Positional + Variable Positional + Keyword __init__(self, a, *b, c=None )
Positional + Variable Positional + Variable Keyword __init__(self, a, *b, **kwargs )
Keyword Only __init__(self, *, a=None )
Positional + Keyword Only __init__(self, a, *, b=None )
Nó cũng thực hiện _
quy ước -prefix tiêu chuẩn để cho phép __init__
các biến -private sẽ không được gán cho các cá thể lớp.
from functools import wraps
import inspect
def auto_assign_arguments(function):
@wraps(function)
def wrapped(self, *args, **kwargs):
_assign_args(self, list(args), kwargs, function)
function(self, *args, **kwargs)
return wrapped
def _assign_args(instance, args, kwargs, function):
def set_attribute(instance, parameter, default_arg):
if not(parameter.startswith("_")):
setattr(instance, parameter, default_arg)
def assign_keyword_defaults(parameters, defaults):
for parameter, default_arg in zip(reversed(parameters), reversed(defaults)):
set_attribute(instance, parameter, default_arg)
def assign_positional_args(parameters, args):
for parameter, arg in zip(parameters, args.copy()):
set_attribute(instance, parameter, arg)
args.remove(arg)
def assign_keyword_args(kwargs):
for parameter, arg in kwargs.items():
set_attribute(instance, parameter, arg)
def assign_keyword_only_defaults(defaults):
return assign_keyword_args(defaults)
def assign_variable_args(parameter, args):
set_attribute(instance, parameter, args)
POSITIONAL_PARAMS, VARIABLE_PARAM, _, KEYWORD_DEFAULTS, _, KEYWORD_ONLY_DEFAULTS, _ = inspect.getfullargspec(function)
POSITIONAL_PARAMS = POSITIONAL_PARAMS[1:]
if(KEYWORD_DEFAULTS ): assign_keyword_defaults (parameters=POSITIONAL_PARAMS, defaults=KEYWORD_DEFAULTS)
if(KEYWORD_ONLY_DEFAULTS): assign_keyword_only_defaults(defaults=KEYWORD_ONLY_DEFAULTS )
if(args ): assign_positional_args (parameters=POSITIONAL_PARAMS, args=args )
if(kwargs ): assign_keyword_args (kwargs=kwargs )
if(VARIABLE_PARAM ): assign_variable_args (parameter=VARIABLE_PARAM, args=args )
Ghi chú:
Tôi đã bao gồm các bài kiểm tra, nhưng đã thu gọn chúng vào dòng cuối cùng ( 58 ) cho ngắn gọn. Bạn có thể mở rộng các bài kiểm tra, kiểm tra chi tiết tất cả các trường hợp sử dụng tiềm năng, bằng cách thêm find/replace
tất cả các $
ký tự bằng một dòng mới.
autoassign
công thức kích hoạt và cáchautoargs
triển khai thay thế tại: Cách tốt nhất để gán thuộc tính tự động trong Python là gì và đó có phải là một ý tưởng hay không? - Stack Overflow