#coding: utf8

# formateado por http://www.sweetapp.com/cgi-bin/cgi-styler-form.py

from itertools import count
import copy


###########################################################
# Acceso a atributos

class C (object):
        
def __init__(self):
                
self.y = 0

        
def __getattribute__(self, name):
                
print 'getattribute', name
                
return object.__getattribute__(self, name)

        
def getx(self):
                
print 'getx'
                
return self.y

        
x = property(fget = getx)

        
def __getattr__(self, name):
                
print 'getattr', name
                
raise AttributeError



###########################################################
# Interfaz de iteración

def myloop(f, l):
        
it = l.__iter__()
        
try:
                
while True:
                        
i = it.next()
                        
f(i)
        
except StopIteration:
                
return
        
return


class EneVecesUno (object):
        
def __init__(self, n):
                
self.count = 0
                
self.n = n

        
def __iter__(self):
                
return self

        
def next(self):
                
self.count += 1
                
if self.count <= self.n:
                        
return 1
                
else:
                        
raise StopIteration



###########################################################
# Generators

# La papa, el mágico Erastotenes
def sieve(gen):
        
x = gen.next()
        
yield x

        
for n in sieve(y for y in gen if y % x > 0):
                
yield n

# En primos tenemos TODOS los primos!
primos = sieve(count(2))


# Ping pong, como el deporte
def mandar(msg):
        
v = yield msg
        
while v != 'fin':
                
print v
                
v = yield msg

ping = mandar('ping')
pong = mandar('pong')

def pingpong(n):
        
po = pong.next()
        
pi = ping.next()
        
for i in range(n):
                
po = pong.send(pi)
                
pi = ping.send(po)



###########################################################
# Decorators

def logcall(f):
        
mod = f.__module__
        
fname = f.func_name
        
file = f.func_code.co_filename
        
line = f.func_code.co_firstlineno

        
def new_f(*args, **kwargs):
                
print "%s  (%s) in %s:%d\n" % (fname, mod, file, line)
                
return f(*args, **kwargs)
        
return new_f


@
logcall
def f(x):
        
return x ** 2


@
dataflow
def query(q):
        
# ...
        
# r = db.query(...)
        
# ...
        
return r

res = query("select ...")


@
wait_for("evento")
def query(q):
        
# ...
        
return r


@
checkaccess(nivel)
def operacion():
        
# ...
        
return r



###########################################################
# with statement

class Protegido (object):
        
def __init__(self, val):
                
self.x = val
                
self.prev = None

        
def __enter__(self):
                
self.prev = copy.copy(self.x)
                
return self.x

        
def __exit__(self, type, val, tb):
                
if type:
                        
self.x = self.prev
                        
raise
                
else:
                        
self.prev = None

o = Protegido([1, 2, 3])
with o as i:
        
i.append(4)
        
# ...



###########################################################
# Fin!