Python: How to dynamically change dict and list object methods?

Here is the layout of what I want to do:

alist = [1,2,3,4,5]   # create a vanilla python list object
replacef (alist)      # replace __setitem__, extend,... with custom functions
alist[0]=2            # now the custom __setitem__ is called

This is for a DSL project, where the syntax should be as close as possible to a regular python, so a list of subclasses and making a user call look like alist = MyList (1,2,3,4,5) is undesirable. Also, since DSL needs to coexist with other libraries, a globally changing list and dict are not an option ...

I tried to create instance methods and set them directly on an object like alist.append = myFunc, but Python says these properties are read-only. Changing the attribute is __class__also not allowed.

Am I trying to do this even in Python?

Update : here are some conclusions about what is possible with a subclass of an object:

Given:

class y(object):
    def __init__(self,a,b,c):
    self.a = a
    self.b = b
    self.c = c
def f(self):
    print self
    print self.a
    print self.b
    print self.c

class x(object):
def __init__(self,a,b,c):
    self.a = a
    self.b = b
    self.c = c
def f(self):
    print "x.f()"

>>> objy = y(1,2,3)
>>> objx = x(4,5,6)
>>> objy.f()
  <__main__.y object at 0x02612650>
  1
  2
  3
>>> objx.f()
  x.f()

objx " " :

>>> objx.__class__ = y
>>> objx.f()
<__main__.y object at 0x02612D90>
4
5
6

, / , javascript:

>>> def g(self,p):
       print self
       print p
>>> import new
>>> objy.g = new.instancemethod(g,objy,y)
>>> objy.g(42)
<__main__.y object at 0x02612650>
42

, C, dict list:

>>> def mypop(self):
        print "mypop"
        list.mypop(self)


>>> alist.pop = new.instancemethod(mypop,alist,list) 

AttributeError: 'list' object attribute 'pop' is read-only

>>> x = [1,2,3,4,5]
>>> x.__class__ = mylist

TypeError: __class__ assignment: only for heap types

- alist = replacef (alist) , replacef __setattribute__ :

alist = [1,2,3,4,5]
aDSLObject.items = alist #  __setattribute__ calls replacef on alist
alist[0] = ....

, , , , C - - ?

+3
2

, "alist = MyList (1,2,3,4,5)" replaceref?

def replacef(l):
    return MyList(l) # Return instance of list subclass that has custom __setitem__

alist = [1,2,3,4,5]
alist = replaceref(alist)

, , replaceref setitem.

+4

" , ". , MyList() list(). .

Ruby , , , . Ruby . , Ruby , Python, Ruby.

, MyList() MyList().

MyList(), :

class MyList(object):
    def __init__(self, *args):
        self.lst = args
    # add other methods to MyList() here

MyList(1, 2, 3, 4), , lst : [1, 2, 3, 4]

, MyList , ? :

new_list = [1, 3, 5]
x = MyList(new_list)

x: [[1, 3, 5]]

MyList() :

def ensure_list(seq):
    try:
        seq[0]
        return seq
    except TypeError:
        return list(seq)

class MyList(object):
    def __init__(self, seq):
        self.lst = ensure_list(seq)
    # add other methods to MyList() here

. list(), ensure_list(). ensure_list() , ; , , -, , . , ensure_list() list(seq), . , .

+2

Source: https://habr.com/ru/post/1725193/


All Articles