1. Metaclass


PyPy source code has a pair and ExtendableType


"""
Two magic tricks for classes:
    class X:
        __metaclass__ = extendabletype
        ...
    # in some other file...
    class __extend__(X):
        ...      # and here you can add new methods and class attributes to X
Mostly useful together with the second trick, which lets you build
methods whose 'self' is a pair of objects instead of just one:
    class __extend__(pairtype(X, Y)):
        attribute = 42
        def method((x, y), other, arguments):
            ...
    pair(x, y).attribute
    pair(x, y).method(other, arguments)
This finds methods and class attributes based on the actual
class of both objects that go into the pair(), with the usual
rules of method/attribute overriding in (pairs of) subclasses.
For more information, see test_pairtype.
"""

class extendabletype(type):
    """A type with a syntax trick: 'class __extend__(t)' actually extends
    the definition of 't' instead of creating a new subclass."""
    def __new__(cls, name, bases, dict):
        if name == '__extend__':
            for cls in bases:
                for key, value in dict.items():
                    if key == '__module__':
                        continue
                    # XXX do we need to provide something more for pickling?
                    setattr(cls, key, value)
            return None
        else:
            return super(extendabletype, cls).__new__(cls, name, bases, dict)


def pair(a, b):
    """Return a pair object."""
    tp = pairtype(a.__class__, b.__class__)
    return tp((a, b))   # tp is a subclass of tuple

pairtypecache = {}

def pairtype(cls1, cls2):
    """type(pair(a,b)) is pairtype(a.__class__, b.__class__)."""
    try:
        pair = pairtypecache[cls1, cls2]
    except KeyError:
        name = 'pairtype(%s, %s)' % (cls1.__name__, cls2.__name__)
        bases1 = [pairtype(base1, cls2) for base1 in cls1.__bases__]
        bases2 = [pairtype(cls1, base2) for base2 in cls2.__bases__]
        bases = tuple(bases1 + bases2) or (tuple,)  # 'tuple': ultimate base
        pair = pairtypecache[cls1, cls2] = extendabletype(name, bases, {})
    return pair
Copy the code


Said extendabletype first. A partial class Python implementation in C#.


Then there’s pair and PairType. A pairType is a new class created from two classes that inherit from the pairType constructed from the base class of the two classes. Or a tuple.

What’s the use? You can implement multimethod.

class __extend__(pairtype(int, int)):
    def foo((x, y)):
        print 'int-int: %s-%s' % (x, y)

class __extend__(pairtype(bool, bool)):
    def bar((x, y)):
        print 'bool-bool: %s-%s' % (x, y)

pair(False, True).foo()  # prints 'int-int: False, True'
pair(123, True).foo()  # prints 'int-int: 123, True'
pair(False, True).bar()  # prints 'bool-bool: False, True'
pair(123, True).bar()  # Oops, no such method
Copy the code


As if the metaclass in this example is just a supporting role, all the fun is in the pair…

Let’s do another one.

class GameObjectMeta(type): def __new__(mcls, clsname, bases, _dict): for k, v in _dict.items(): if isinstance(v, (list, set)): _dict[k] = tuple(v) # mutable obj not allowed cls = type.__new__(mcls, clsname, bases, _dict) all_gameobjects.add(cls) for b in bases: game_objects_hierarchy.add((b, cls)) return cls @staticmethod def _dump_gameobject_hierarchy(): with open('/dev/shm/gomap.dot', 'w') as f: f.write('digraph {\nrankdir=LR; \n') f.write('\n'.join([ '"%s" -> "%s"; ' % (a.__name__, b.__name__) for a, b in game_objects_hierarchy ])) f.write('}') def __setattr__(cls, field, v): type.__setattr__(cls, field, v) if field in ('ui_meta', ): return log.warning('SetAttr: %s.%s = %s' % (cls.__name__, field, repr(v)))Copy the code


This is a piece of code extracted from the game I wrote (click the link on my signature). Replace all mutable containers on the class with immutable ones, and record the inheritance relationship.


The value of the class is shared globally, and the logic code accidentally changes the value of the class. When testing on a single machine, it cannot be detected, and then put it on the line. Tragedy… Racking their brains at that time did not think of this problem is a snap back… This is added when a problem is found, and it is not allowed to modify the class.


Inheritance relationships are recorded for the purpose of drawing class diagrams.

There is commonly used to do data injection

metadata = {} def gen_metafunc(_for): def metafunc(clsname, bases, _dict): meta_for = getattr(_for, clsname) meta_for.ui_meta = UIMetaDescriptor() if meta_for in metadata: raise Exception('%s ui_meta redefinition! ' % meta_for) metadata[meta_for] = _dict return metafunc from gamepack.thb import characters __metaclass__ = gen_metafunc(characters.sakuya) class Sakuya: # So this is not a class, Char_name = u' portrait-sakuya' port_image = 'thb-portrait-sakuya' figure_image = 'thb-figure-sakuya' Miss_sound_effect = 'considered - CV - sakuya_miss description = (u' long | DB completely natural and unrestrained PAD 16 night sakura sake night strength: 4 | r \ n \ n 'u' | | r: G time Locking technology | | B r, at the start of the preparation stage, you perform an additional stages of play. Fly knife \ n \ n 'u' | G | r: you can take a piece of equipment when using barrage 】 【 or play the card. The [barrage] used in this way has no distance limitation. \ n \ n 'u' | DB (painter: small D @ star の delusion township, CV: VV) | r ')Copy the code

Ruby party don’t spray, I know you can do more elegant…

2. The Python sandbox escape http://blog.delroth.net/2013/03/escaping-a-python-sandbox-ndh-2013-quals-writeup/ break through the Python code

3. PEP302 New Import Hook is currently porting the aforementioned pure Python game to The Unity engine. If you’ve played With Unity, you’ll know that the resources for Unity’s games are all bundled together, and the Python interpreter isn’t happy without a separate file… So I wrote an import hook and used the API provided by Unity to read py files.

# -*- coding: utf-8 -*- # -- stdlib -- import imp import sys # -- third party -- # -- own -- from clr import UnityEngine, WarpGateController # -- code -- class UnityResourceImporter(object): known_builtin = ( 'sys', 'imp', 'cStringIO', 'gevent_core', 'gevent_ares', 'gevent_util', 'gevent_semaphore', 'msgpack_packer', 'msgpack_unpacker', 'UnityEngine', ) def __init__(self, bases, unity_loader): self.bases = bases self.last_fullname = '' self.last_text = '' self.last_ispkg = False self.unity_load = unity_loader def find_module(self, fullname, path=None): if fullname in sys.modules: return self head = fullname.split('.')[0] if head in self.known_builtin: return None rst = self.do_load_module(fullname) if rst: self.last_text, self.last_ispkg = rst self.last_fullname = fullname return self else: return None def load_module(self, fullname): if fullname in sys.modules: return sys.modules[fullname] if fullname ! = self.last_fullname: self.find_module(fullname) try: code = self.last_text ispkg = self.last_ispkg mod = sys.modules.setdefault(fullname, imp.new_module(fullname)) mod.__file__ = "%s>" % fullname mod.__loader__ = self if ispkg: mod.__path__ = [] mod.__package__ = fullname else: mod.__package__ = fullname.rpartition('.')[0] co = compile(code, mod.__file__, 'exec') exec(co, mod.__dict__) return mod except Exception as e: UnityEngine.Debug.LogError('Error importing %s%s' % (fullname, e)) raise ImportError(e) def do_load_module(self, fullname): fn = fullname.replace('.', '/') asset = self.try_load(fn + '.py') if asset is not None: return asset, False asset = self.try_load(fn + '/__init__.py') if asset is not None: return asset, True def try_load(self, filename): for b in self.bases: asset = self.unity_load(b + filename) if asset is not None: return asset return None sys.meta_path.append(UnityResourceImporter([ 'Python/THBattle/', 'Python/Site/', 'Python/Stdlib/', ], WarpGateController.GetTextAsset))Copy the code

The required Extension Module is statically compiled into the interpreter, so it is not considered.

4. List of operations that can be executed in batches

class BatchList(list): def __getattribute__(self, name): try: list_attr = list.__getattribute__(self, name) return list_attr except AttributeError: pass return list.__getattribute__(self, '__class__')( getattr(i, name) for i in self ) def __call__(self, *a, **k): return list.__getattribute__(self, '__class__')( f(*a, **k) for f in self ) class Foo(object): def __init__(self, v): self.value = v def foo(self): print 'Foo! ', self.value foo = Foo(1) foo.foo() # Foo! 1 foos = BatchList(Foo(I) for I in xrange(10)) foos.value # BatchList([0, 1, 2, 3... 9]) foos. Foo() # you can guess itCopy the code

This is actually not very dark magic, but it feels very useful and a little dangerous, so put it up.

I think so much for the time being, and I’ll make up for it later.