Scoping Probleme

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Ich kanns mir einfach nicht erklären:

Code: Alles auswählen

import sys
from warnings import warn


def deprecate(cls, **mapping):
    old_getattr = getattr(cls, '__getattr__', None)
    if old_getattr is None:
        old_getattr = getattr(cls, '__getattribute__', None)
    old_setattr = getattr(cls, '__setattr__', None)
    old_delattr = getattr(cls, '__delattr__', None)
    
    real_mapping = {}
    for old_name, data in mapping.iteritems():
        type_, new_name, arg_rewrites = data
        rewrites = dict([(b, a) for a, b in arg_rewrites.items()])
        if type_ == 'attribute':
            def _get(self):
                warn(DeprecationWarning('%r is deprecate, see %r' %
                                        (old_name, new_name)))
                return old_getattr(self, new_name)
        elif type_ == 'method':
            def _get(self):
                warn(DeprecationWarning('%r is deprecate, see %r' %
                                        (old_name, new_name)))
                f = old_getattr(self, new_name)
                def _wrapped(*args, **kwargs):
                    new_kwargs = {}
                    for key, value in kwargs.iteritems():
                        if key in rewrites:
                            new_kwargs[key] = kwargs[rewrites[key]]
                        else:
                            new_kwargs[key] = kwargs[key]
                    return f(*args, **new_kwargs)
                _wrapped.__name__ = f.__name__
                _wrapped.__doc__ = f.__doc__
                return _wrapped
        else:
            raise AssertionError('invalid mapper value %r' % type_)
        def _set(self, value):
            warn(DeprecationWarning('%r is deprecate, see %r' %
                                    (old_name, new_name)))
            old_setattr(self, new_name, value)
        def _del(self):
            warn(DeprecationWarning('%r is deprecate, see %r' %
                                    (old_name, new_name)))
            old_delattr(self, new_name)
        real_mapping[old_name] = property(_get, _set, _del,
                                         'deprecate method %r, see %r' %
                                         (old_name, new_name))
    
    def _getattr(self, attr):
        if attr in real_mapping:
            t = real_mapping[attr]
            return t.__get__(self)
        return old_getattr(self, attr)
        
    def _setattr(self, attr, value):
        if attr in real_mapping:
            t = real_mapping[attr]
            t.__set__(self, value)
        old_setattr(self, attr, value)
        
    def _delattr(self, attr):
        if attr in real_mapping:
            t = real_mapping[attr]
            t.__del__(self, value)
        old_delattr(self, attr, value)
    
    cls.__getattr__ = _getattr
    cls.__setattr__ = _setattr
    cls.__delattr__ = _delattr

deprecate.method = lambda name, **args: ('method', name, args)
deprecate.attribute = lambda name: ('attribute', name, {})


def test():
    """
    Test Cases.
    """
    
    class MyClass(object):

        def __init__(self):
            self._my_attribute = 'default name'

        def my_method(self, my_args=None):
            if my_args is None:
                name = self._my_attribute
            else:
                name = my_args
            return 'Hello %s!' % name

    deprecate(MyClass,
        myMethod=deprecate.method('my_method', myArgs='my_args'),
        myAttribute=deprecate.attribute('_my_attribute')
    )

    obj = MyClass()
    print '1', obj.myAttribute
    print '2', obj._my_attribute
    print '3', obj.my_method()
    print '4', obj.myMethod()


if __name__ == '__main__':
    test()
Ausgabe:

Code: Alles auswählen

blackbird@volverine:~/Developement/area51$ frog apichange.py
apichange.py:23: DeprecationWarning: 'myMethod' is deprecate, see 'my_method'
  warn(DeprecationWarning('%r is deprecate, see %r' %
1 <bound method MyClass.my_method of <__main__.MyClass object at 0xb7cfcc8c>>
2 default name
3 Hello default name!
apichange.py:28: DeprecationWarning: 'myMethod' is deprecate, see 'my_method'
  warn(DeprecationWarning('%r is deprecate, see %r' %
4 Hello default name!
Warum bekomm ich am Anfang "'myMethod' is deprecate, see 'my_method'", wo ich eindeutig auf "myAttribute" zugreife? :shock:
TUFKAB – the user formerly known as blackbird
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Hmmm. Schon klar. Eine For Schleife ist kein eigener Frame. Das heißt wenn ich eine Funktion proxy(old_name, data) oder sowas mach geht das.

Damit gibts bis zu 3 verschachtelte Funktionen. AUA
TUFKAB – the user formerly known as blackbird
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Für Interessierte, der Sourcecode ist hier: http://trac.pocoo.org/repos/sandbox/apichange.py
TUFKAB – the user formerly known as blackbird
Antworten