Python练习题答案: 懒惰的初始【难度:4级】--景越Python编程实例训练营,1000道上机题等你来挑战

懒惰的初始【难度:4级】:

答案1:

class Person(metaclass=LazyInit):
  def __init__(self, name, age): pass

class Circle(metaclass=LazyInit):
  def __init__(self, x, y, ray): pass

a_person = Person('Luke', 21)

# Use test.describe (or Test.describe) to describe your test suite
test.describe("Basics")

# Use "it" calls to describe the specific test case
test.it("should work with first example test case")

# you can also use the lower level test.expect. If you use test.expect directly then
# you should provide a custom error message, as the default one will be pretty useless
# to users trying to pass the kata.
test.expect(a_person.name == 'Luke', 'Ehi, my name is Luke')
test.expect(a_person.age == 21, 'Ehi, I`m 21 years old')

# Use test.describe (or Test.describe) to describe your test suite
test.describe("More arguments")

# Use "it" calls to describe the specific test case
test.it("should work with different numbers of arguments")

a_circle = Circle(0, 0, 5)

test.expect(a_circle.x == 0, 'X coordinate is 0')
test.expect(a_circle.y == 0, 'Y coordinate is 0')
test.expect(a_circle.ray == 5, 'The ray is 5')

class Car(metaclass=LazyInit):
  def __init__(self, model, color, plate, year): pass

class Nothing(metaclass=LazyInit):
    def __init__(self, nothing): pass
    
a_car = Car('Ford Ka', 'Blue', 'AF329SZ', 1999)
a_nothing = Nothing('nothing')

test.expect(a_car.model == 'Ford Ka', 'I`m a KA')
test.expect(a_car.color == 'Blue', 'Yeah I`m blue but not sad!!')
test.expect(a_car.plate == 'AF329SZ', 'My number is AF329SZ... call me!!')
test.expect(a_car.year== 1999, 'I`m still young yuo know!!')
test.expect(a_nothing.nothing == 'nothing', 'I`m nothing!!!')

答案2:

from functools import wraps

class LazyInit(type):
    
    @staticmethod
    def decorate(func):
        @wraps(func)
        def wrapper(*args):
            self   = args[0]
            fields = args[1:]
            func(*args)
            for fName,fVal in zip(func.__code__.co_varnames[1:], fields):
                self.__dict__[fName] = fVal
        return wrapper
            
    
    def __new__(cls, name, parent, dct):
        dct['__init__'] = LazyInit.decorate(dct['__init__'])
        return type.__new__(cls, name, parent, dct)

答案3:

from functools import wraps

# metaclass
class LazyInit(type):
    def __new__(meta, clsname, bases, clsdict):      
        clsdict['__init__'] = new_init(clsdict['__init__'])
        return super().__new__(meta, clsname, bases, clsdict)
        
# decorator
def new_init(old_init):
  def autoinit(*args):
      formals = old_init.__code__.co_varnames
      for name, value in zip(formals[1:], args[1:]):
          setattr(args[0], name, value) 
  return autoinit​

答案4:

class LazyInit(type):
    def __new__(mcs, name, bases, namespace):
        init_args = namespace['__init__'].__code__.co_varnames[1:]

        def __init__(self, *args):
            self.__dict__.update(dict(zip(init_args, args)))

        namespace['__init__'] = __init__
        return super().__new__(mcs, name, bases, namespace)

答案5:

import inspect
class LazyInit(type):
     def __init__(child, self, *args, **kwargs):
        names = child.__init__.__code__.co_varnames[1:]
        def patch(self, *args):
            for i,v in enumerate(args): self.__setattr__(names[i], v)
        child.__init__ = patch​

答案6:

from functools import wraps

def decorator(cls):
    @wraps(cls)
    def wrapper(*args, **kwargs):
        for n, a in zip(args, cls.__init__.__code__.co_varnames[1:]):
            setattr(cls, a, n)
        return cls
    return wrapper

class LazyInit(type):
    def __new__(cls, *args, **kwargs):
        clsobj = decorator(super(LazyInit, cls).__new__(cls, *args, **kwargs))
        return clsobj
​

答案7:

def oncall_init(init_ref):
    def wrapper(obj, *values):
        attrs = init_ref.__code__.co_varnames[1:]
        [setattr(obj, attr, value) for attr, value in zip(attrs, values)]

        return init_ref(obj, *values)
    return wrapper
        

class LazyInit(type):
    def __new__(cls, name, bases, dct):
        dct['__init__'] = oncall_init(dct['__init__'])
        cls = super().__new__(cls, name, bases, dct)
        return cls​

答案8:

from inspect import signature


class LazyInit(type):
    def __init__(self, *args, **kwargs):
        init_method = args[2]["__init__"]
        init_parameters = signature(init_method).parameters

        parameter_names = [
            parameter_name for parameter_name, _ in init_parameters.items()
            if parameter_name != "self"
        ]

        def __new__init__(self, *args, **kwargs):
            init_method(self, *args, **kwargs)

            for parameter_index, parameter_name in enumerate(parameter_names):
                setattr(self, parameter_name, args[parameter_index])

        self.__init__ = __new__init__
​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值