How to do Obj-C Categories in Python?

后端 未结 3 1030
被撕碎了的回忆
被撕碎了的回忆 2021-02-06 02:49

Obj-C (which I have not used for a long time) has something called categories to extend classes. Declaring a category with new methods and compiling it into your program, all in

相关标签:
3条回答
  • 2021-02-06 03:31

    I came up with this implementation of a class decorator. I'm using python2.5 so I haven't actually tested it with decorator syntax (which would be nice), and I'm not sure what it does is really correct. But it looks like this:

    pycategories.py

    """
    This module implements Obj-C-style categories for classes for Python
    
    Copyright 2009 Ulrik Sverdrup <ulrik.sverdrup@gmail.com>
    License: Public domain
    """
    
    def Category(toclass, clobber=False):
        """Return a class decorator that implements the decorated class'
        methods as a Category on the class @toclass
    
        if @clobber is not allowed, AttributeError will be raised when
        the decorated class already contains the same attribute.
        """
        def decorator(cls):
            skip = set(("__dict__", "__module__", "__weakref__", "__doc__"))
            for attr in cls.__dict__:
                if attr in toclass.__dict__:
                    if attr in skip:
                        continue
                    if not clobber:
                        raise AttributeError("Category cannot override %s" % attr)
                setattr(toclass, attr, cls.__dict__[attr])
            return cls
        return decorator
    
    0 讨论(0)
  • 2021-02-06 03:33

    Python's setattr function makes this easy.

    # categories.py
    
    class category(object):
        def __init__(self, mainModule, override = True):
            self.mainModule = mainModule
            self.override = override
    
        def __call__(self, function):
            if self.override or function.__name__ not in dir(self.mainModule):
                setattr(self.mainModule, function.__name__, function)
    

     

    # categories_test.py
    
    import this
    from categories import category
    
    @category(this)
    def all():
        print "all things are this"
    
    this.all()
    >>> all things are this
    
    0 讨论(0)
  • 2021-02-06 03:50

    Why not just add methods dynamically ?

    >>> class Foo(object):
    >>>     pass
    >>> def newmethod(instance):
    >>>     print 'Called:', instance
    ...
    >>> Foo.newmethod = newmethod
    >>> f = Foo()
    >>> f.newmethod()
    Called: <__main__.Foo object at 0xb7c54e0c>
    

    I know Objective-C and this looks just like categories. The only drawback is that you can't do that to built-in or extension types.

    0 讨论(0)
提交回复
热议问题