internals - Why is __code__ for a function(Python) mutable -
in previous question yesterday, in comments, came know in python __code__
atrribute of function mutable. hence can write code following
def foo(): print "hello" def foo2(): print "hello 2" foo() foo.__code__ = foo2.__code__ foo()
output
hello hello 2
i tried googling, either because there no information(i highly doubt this), or keyword (__code__
) not searchable, couldn't find use case this.
it doesn't seem "because things in python mutable" reasonable answer either, because other attributes of functions — __closure__
, __globals__
— are explicitly read-only (from objects/funcobject.c):
static pymemberdef func_memberlist[] = { {"__closure__", t_object, off(func_closure), restricted|readonly}, {"__doc__", t_object, off(func_doc), py_write_restricted}, {"__globals__", t_object, off(func_globals), restricted|readonly}, {"__module__", t_object, off(func_module), py_write_restricted}, {null} /* sentinel */ };
why __code__
writable while other attributes read-only?
the fact is, things in python are mutable. real question is, why __closure__
, __globals__
not?
the answer appears simple. both of these things containers variables function might need. code object not carry closed-over , global variables around it; merely knows how them function. grabs actual values out of these 2 attributes when function called.
but scopes mutable, answer unsatisfying. need explain why modifying these things in particular break stuff.
for __closure__
, can structure. not mapping, tuple of cells. doesn't know names of closed-over variables. when code object looks closed-over variable, needs know position in tuple; match one-to-one co_freevars
read-only. , if tuple of wrong size or not tuple @ all, mechanism breaks down, violently (read: segfaults) if underlying c code isn't expecting such situation. forcing c code check type , size of tuple needless busy-work can eliminated making attribute read-only. if try replace __code__
taking different number of free variables, you error, size right.
for __globals__
, explanation less obvious, i'll speculate. scope lookup mechanism expects have access global namespace @ times. indeed, bytecode may hard-coded go straight global namespace, if compiler can prove no other namespace have variable particular name. if global namespace none
or other non-mapping object, c code could, once again, violently misbehave. again, making code perform needless type checks waste of cpu cycles.
another possibility (normally-declared) functions borrow reference module's global namespace, , making attribute writable cause reference count messed up. imagine design, i'm not sure it's great idea since functions can constructed explicitly objects lifetimes might shorter of owning module, , these need special-cased.
Comments
Post a Comment