What is and is not available to class methods in python?

My limited understanding is that the second argument types. FunctionTypes ( dict

) defines what is available to the function code. I am curious how this turns out when you create internal functions. To illustrate what I mean, if I try to copy a function dynamically:

a = 'test'
def foo():
    print(a)

bar = types.FunctionType(
    foo.__code__, 
    globals(), 
    'bar', 
    foo.__defaults__, 
    foo.__closure__
)

      

This seems to work with globals (), but I haven't missed anything? More confusing is the class method. If I do something like this:

a = 'test'

class Foo(object):
    b = 'Foo prints this'

    def myfunc():
        print(a, self.b)

Bar = type('Bar', tuple(), dict())
Bar.b = 'Bar prints this'

ns = globals()
#should I do ns.update(something) here?

f = Foo.myfunc
Bar.myfunc = types.FunctionType(f.__code__, ns, 'myfunc', ...)

      

This example works, but not more complicated:

import imp
import builtins

class Foo(object):
    def __init__(self):
        super().__init__() # super(Foo, self) also fails

mod = imp.new_module('test')
mod.__builtins__ = builtins
mod.Foo = type('Foo', tuple(), dict())

f = Foo.__init__
ns = {}
ns.update(mod.__dict__) #missing something here

mod.Foo.__init__ = types.FunctionTypes(f.__code__, ns, '__init__', ...)

      

Can anyone please highlight what should be in ns

? What is available for a class method and what is not?

I'm not trying to get this code to work, I'm looking more for an explanation of why it doesn't.

+3


source to share


1 answer


The problem is that "copying" an attribute __closure__

does not create a copy; that the execution context itself, in which the function object itself ( def __init__

) was executed; in support of lexical rules in python. Taking a look:

>>> [cell.cell_contents for cell in f.__closure__]
[<class '__main__.Foo'>]

      



Unsurprisingly, this is the class in which it was defined. I'm not sure about an easy way to create a new object cell

other than using exec

it to create a new class and method; You could probably copy the new cell to additional methods to be added to the new class, but both the core and the class will be completely new.

0


source







All Articles