Điều này có thể hơi muộn nhưng tôi đã thực hiện một giải pháp bằng cách sử dụng Python Meta-Classes (phiên bản trang trí bên dưới).
Khi __init__
được gọi trong thời gian chạy, nó lấy từng đối số và giá trị của chúng và gán chúng làm biến thể hiện cho lớp của bạn. Bằng cách này, bạn có thể tạo một lớp giống như cấu trúc mà không phải gán mọi giá trị theo cách thủ công.
Ví dụ của tôi không có lỗi kiểm tra nên dễ theo dõi hơn.
class MyStruct(type):
def __call__(cls, *args, **kwargs):
names = cls.__init__.func_code.co_varnames[1:]
self = type.__call__(cls, *args, **kwargs)
for name, value in zip(names, args):
setattr(self , name, value)
for name, value in kwargs.iteritems():
setattr(self , name, value)
return self
Đây là hành động.
>>> class MyClass(object):
__metaclass__ = MyStruct
def __init__(self, a, b, c):
pass
>>> my_instance = MyClass(1, 2, 3)
>>> my_instance.a
1
>>>
Tôi đã đăng nó trên reddit và / u / matchu đã đăng một phiên bản trang trí sạch hơn. Tôi khuyến khích bạn sử dụng nó trừ khi bạn muốn mở rộng phiên bản siêu dữ liệu.
>>> def init_all_args(fn):
@wraps(fn)
def wrapped_init(self, *args, **kwargs):
names = fn.func_code.co_varnames[1:]
for name, value in zip(names, args):
setattr(self, name, value)
for name, value in kwargs.iteritems():
setattr(self, name, value)
return wrapped_init
>>> class Test(object):
@init_all_args
def __init__(self, a, b):
pass
>>> a = Test(1, 2)
>>> a.a
1
>>>