In [1]:
def foo():
    return 1

foo()


Out[1]:
1

In [8]:
def foo(x):
    print locals()
    
foo(1000)


{'x': 1000}

In [9]:
def outter():
    x = 1
    def inner():
        print x
    inner()
    
outter()


1

In [22]:
#issubclass(int, object)
def foo():
    pass

foo.__class__

issubclass(foo.__class__, object)


Out[22]:
True

In [24]:
def add(a, b):
    return a+b

def sub(a, b):
    return a-b

def apply(func, a, b):
    return func(a,b)

print apply(add, 1, 2)
print apply(sub, 2, 1)


3
1

In [28]:
def outter():
    def inner():
        print "inside inner"
    return inner

foo = outter()
print foo
foo()


<function inner at 0x036EEF30>
inside inner

In [35]:
def outer():
    x = "this is x on outer"
    def inner():
        print x
    return inner

foo = outer()
foo.func_closure
foo()


this is x on outer

In [37]:
def outer(x):
    def inner():
        print x
    return inner

foo = outer(1)
foo()
foo = outer(2)
foo()


1
2

In [43]:
def outer(some_func):
    def inner():
        print "before `some_func`"
        ret = some_func()
        return ret+1
    return inner

def some_func():
    return 1

decorated = outer(some_func)
print decorated()
print '----------------'

x2_decorated = outer(decorated)
print x2_decorated()


before `some_func`
2
----------------
before `some_func`
before `some_func`
3

In [48]:
class Coordinate(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return "coord: " + str(self.__dict__)
    
def add(a, b):
    return Coordinate(a.x + b.x, a.y + b.y)

def sub(a, b):
    return Coordinate(a.x - b.x, a.y - b.y)

one = Coordinate(100, 200)
two = Coordinate(300, 200)
print add(one, two)
print sub(one, two)


coord: {'y': 400, 'x': 400}
coord: {'y': 0, 'x': -200}

In [50]:
class Coordinate(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return "coord: " + str(self.__dict__)
    
def add(a, b):
    return Coordinate(a.x + b.x, a.y + b.y)

def sub(a, b):
    return Coordinate(a.x - b.x, a.y - b.y)

def wrapper(func):
    def checker(a, b):
        if a.x < 0 or a.y < 0:
            a = Coordinate(a.x if a.x > 0 else 0, a.y if a.y > 0 else 0)
        if b.x < 0 or b.y < 0:
            b = Coordinate(b.x if b.x > 0 else 0, b.y if b.y > 0 else 0)
        ret = func(a, b)
        if ret.x < 0 or ret.y < 0:
            ret = Coordinate(ret.x if ret.x > 0 else 0, ret.y if ret.y > 0 else 0)
        return ret
    return checker

one = Coordinate(100, 200)
two = Coordinate(300, 200)

add = wrapper(add)
sub = wrapper(sub)
print add(one, two)
print sub(one, two)


coord: {'y': 400, 'x': 400}
coord: {'y': 0, 'x': 0}

In [54]:
class Coordinate(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __repr__(self):
        return "coord: " + str(self.__dict__)
    
def wrapper(func):
    def checker(a, b):
        if a.x < 0 or a.y < 0:
            a = Coordinate(a.x if a.x > 0 else 0, a.y if a.y > 0 else 0)
        if b.x < 0 or b.y < 0:
            b = Coordinate(b.x if b.x > 0 else 0, b.y if b.y > 0 else 0)
        ret = func(a, b)
        if ret.x < 0 or ret.y < 0:
            ret = Coordinate(ret.x if ret.x > 0 else 0, ret.y if ret.y > 0 else 0)
        return ret
    return checker

@wrapper
def add(a, b):
    return Coordinate(a.x + b.x, a.y + b.y)

@wrapper
def sub(a, b):
    return Coordinate(a.x - b.x, a.y - b.y)


one = Coordinate(100, 200)
two = Coordinate(300, 200)

#add = wrapper(add)
#sub = wrapper(sub)
print add(one, two)
print sub(one, two)


coord: {'y': 400, 'x': 400}
coord: {'y': 0, 'x': 0}

In [58]:
def logging_arguments(func):
    def inner(*args, **kwargs):
        print "arguments were : %s, %s" % (args, kwargs)
        return func(*args, **kwargs)
    return inner

@logging_arguments
def foo1(x, y=2):
    return x + y

@logging_arguments
def foo2():
    return 2

print foo1(100, 2)
print foo2()


arguments were : (100, 2), {}
102
arguments were : (), {}
2

In [1]:
class EntryExit(object):
    def __init__(self, some_func):
        self.f = some_func
        
    def __call__(self, *args, **kwargs):
        print '>> entering {0} with {1}, {2}'.format(self.f.__name__, *args, **kwargs)
        self.f(*args, **kwargs)
        print '<< leaving {0}'.format(self.f.__name__)
        
@EntryExit        
def some_func(*args, **kwargs):
    print 'inside some_func with {0}, {1}'.format(*args, **kwargs)
    
some_func(1,2,3, a='1', b='2')


>> entering some_func with 1, 2
inside some_func with 1, 2
<< leaving some_func