Skip to content

Instantly share code, notes, and snippets.

@alexey-sveshnikov
Created December 30, 2013 12:03
Show Gist options
  • Save alexey-sveshnikov/8181352 to your computer and use it in GitHub Desktop.
Save alexey-sveshnikov/8181352 to your computer and use it in GitHub Desktop.
Инициализация членов класса для ленивых
#!/usr/bin/python
import inspect
from functools import wraps
class SimpleInitializationMixin(object):
def __new__(cls, *args, **kwargs):
obj = super(SimpleInitializationMixin, cls).__new__(cls, *args, **kwargs)
func_signature = inspect.getargspec(cls.__init__)
defaults = [None] * (len(func_signature.args) - len(func_signature.defaults)) + list(func_signature.defaults)
args_spec = list(reversed(zip(func_signature.args, defaults)))
args_spec.pop() # ignore 'self' argument
for value in args:
if not args_spec:
break
name, _ = args_spec.pop()
setattr(obj, name, value)
for name, default in args_spec:
setattr(obj, name, kwargs.get(name, default))
return obj
def simple_initialization(func):
@wraps(func)
def wrapper(obj, *args, **kwargs):
func_signature = inspect.getargspec(func)
defaults = [None] * (len(func_signature.args) - len(func_signature.defaults)) + list(func_signature.defaults)
args_spec = list(reversed(zip(func_signature.args, defaults)))
args_spec.pop() # ignore 'self' argument
for value in args:
if not args_spec:
break
name, _ = args_spec.pop()
setattr(obj, name, value)
for name, default in args_spec:
setattr(obj, name, kwargs.get(name, default))
func(obj, *args, **kwargs)
return wrapper
class MyClass1(SimpleInitializationMixin):
def __init__(self, one='one', two='two', three=None, four=None):
pass
class MyClass2(object):
@simple_initialization
def __init__(self, one='one', two='two', three=None, four=None):
pass
def main():
for cls in (MyClass1, MyClass2):
obj = cls(one='111')
assert not hasattr(obj, 'self')
assert obj.one == '111'
assert obj.two == 'two'
assert obj.three == None
assert obj.four == None
obj = cls()
assert obj.one == 'one'
assert obj.two == 'two'
assert obj.three == None
assert obj.four == None
obj = cls(1,2,3,4)
assert obj.one == 1
assert obj.two == 2
assert obj.three == 3
assert obj.four == 4
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment