Friday, 15 June 2012

metaprogramming - python modify __metaclass__ for whole program -


Edit: Note that this is a very bad idea in the output code. This was an interesting thing for me, do not do it at home!

Is it possible to modify the __metaclass__ variable for the whole program (interpreter) in Python?

This simple example is working:

  class chat type (type): def __init __ (cls, name, bases, dct): print "class init" , Name super (ChattyType, CLS) .__ init __ (names, locations, DCT) __metaclass __ = ChattyType class data: data pass = data () # print "class init data" print data   < P> But I would love to do the work in the subbold also to be able change of __metaclass__. For example (file m1.py):  
  class A: pass A = A () print  

file main.py:

I understand that Global __metaclass__ is no longer working Python 3.x, But this is not my concern (my code is proof of concept). So is there any way to complete it in Python -2.x?

OK; IMO This is a gross, hairy, dark magic. You should never use it, but especially in the production code. It's just interesting to inquire, however.

You can write a custom importer using the mechanism described in it, and further discussed in Doug Hellman it gives you the tools to complete the work you have done.

I implemented such an importer, just because I was curious. Basically, for the module that you specify through the class variable __ chaty_for __ , it can be imported into the __ dict __ __ metaclass __ Will enter a custom type as the variable>, the first code has been evaluated. If the code in question defines its own __ metaclass __ , then the importer will replace the one already included.

I have not written many importers, so I may have done one or more silly acts by writing this, it will not be inappropriate to apply any module before implementing this importer. . If anybody misses the mistakes / corner cases in execution, please leave a comment.

Source file 1:

  # foo.py class Foo: pass  

source file 2:

 # bar.py class bar: pass  

source file 3:

  # baaz.py class falcon: pass  < / Pre> 

and main event:

  # chattyimport.py import import import import import type class ChattyType (type): def __init __ (CLS, names, bases, DCT): print "Class init", name super (ChattyType, CLS) .__ init __ (names, locations, DCT) class ChattyImporter (object): __chatty_for__ = [] Def __init __ (auto, path_entry): def passed find_module (self , Full name, path = none): If the full name is not in itself .__ chatty_for__: try not to return: if path is not: self.find_results = imp.find_module (full name) and: self.find_results = imp.find_module (Full name, path) Previously imported error: None return (F, FN, (SIP, mode, type)) = self.find_results if typ == imp.PY_SOURCE: Returns self returns no DRH load_module (self, full name): # Print '% s loading module% S'% (type (self) .__ name__, absolute name) (F, FN, (SIP, mode, type)) = self.find_results data = f.read () Fullname: module = sys.modules [full name] in the sys.modules All other: sys.modules [full name] = module = types.ModuleType (full name) module .__ metaclass__ = ChattyType module .__ file__ = fn module. __name__ = full name codeobj = compilation (data, fn, 'executive') codeobj .__ dict__ return module class in the executive module. ChattyImportSomeModules (ChattyImporter): __chatty_for__ = 'foo bar'.split () sys.meta_path.append (ChattyImportSomeModules '')) Import foo # print 'class foo init' import bar # print 'class init bar' import barge  

No comments:

Post a Comment