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