chenyinuo chenyinuo - 23 days ago 12
Python Question

how to fix the _replace method

class type_name:
def __init__(self, fields):
self._fields = fields
self._mutable = False
self.a = self._fields[0]
self.b = self._fields[1]
self.c = self._fields[2]

def _replace(self, **kargs):
if self._mutable:
for key, value in kargs.items():
if key == 'a':
self.a = value
if key == 'b':
self.b = value
if key == 'c':
self.c = value
return None
else:
A = self.a, B = self.b, C = self.c
return self.type_name(**kargs)


the _replace method takes **kargs as input. the _replace method depends on the value stored in the instance name self._mutable.
if self.mutable == True, the instance namess of the object it is called on are changed and the method returns None So, if origin = Point(0,0) and we call origin._replace(y=5), then print(origin) would display as Point(x=0,y=5) because origin is mutated.

If self.mutable == False, it returns a new object of the same class, whose instance name's values are the same, except for those specified in kargs. So, if origin = Point(0,0) and we call new_origin = origin._replace(y=5), then print(origin,new_origin) would display as Point(x=0,y=0) Point(x=0,y=5) because origin is not mutated

I am not sure what is wrong with my function _replace, can someone help me to fix it? thanks

Answer

You __init__() doesn't take keyword arguments, only a list called fields. You either need to change your __init__() method or map the kwargs to a list:

class type_name:
    def __init__(self, fields):
        self._fields = fields
        self._mutable = False 
        self.a = self._fields[0]
        self.b = self._fields[1]
        self.c = self._fields[2]

    def _replace(self, **kwargs):
        if not self._mutable:
            return type_name([kwargs[c] for c in 'abc'])
        for key, value in kwargs.items():
            if key == 'a':
                self.a = value
            if key == 'b':
                self.b = value
            if key == 'c':
                self.c = value
        return None

a = type_name([1,2,3])
b = a._replace(a=3, b=2, c=1)
b.a
# 3

To be honest, I don't like this overloaded use of _replace(). Create 2 different methods.

Comments