Unpacking
lista = [1, 2, 3, 4]
a1, a2, a3, a4 = lista
print(a2)
print(lista)
print(*lista)
Mas general
def f1(*args):
print(args)
print(*args)
def f2(**kwargs):
print(kwargs)
print(*kwargs)
print(", ".join(["{}={}".format(k,v) for k,v in kwargs.items()]))
def f3(*args, **kwargs):
print(args, kwargs)
print("-----F1------")
f1(1,2,3,4,5)
print("-----F2------")
f2(a=10, b=20, c=30)
print("-----F3------")
f3(1,2,4, a=20, r=10, s="un String")
%reset -f
a = {
"a":10,
"b":20
}
b = {
"b":100,
"c":200
}
print(a)
print(b)
c = {**a, **b}
print(c)
d = {**b, **a}
print(d)
%reset -f
Aceptamos de todo
def f1(a1, a2, *args, k1=10, k2=20, **kwargs):
print(f"a1={a1}, a2={a2}")
print(f"args: {args}")
print(f"k1={k1}")
print(f"k2={k2}")
print(f"kwargs: {kwargs}")
f1(1, 2, 3, k1=20, k2=30, a=100, b=200)
Ahora sin *args
def f1(a1, a2, k1=10, k2=20, **kwargs):
print(f"a1={a1}, a2={a2}")
print(f"k1={k1}")
print(f"k2={k2}")
print(f"kwargs: {kwargs}")
f1(1, 2, 3, k1=20, k2=30, a=100, b=200)
Por que pasa esto
def f1(a1, a2, k1=10, k2=20):
print(f"a1={a1}, a2={a2}")
print(f"k1={k1}")
print(f"k2={k2}")
f1(1, 2, 3, 4)
La solucion: *
def f1(a1, a2, *, k1=10, k2=20):
print(f"a1={a1}, a2={a2}")
print(f"k1={k1}")
print(f"k2={k2}")
try:
f1(1,2,3,4)
except TypeError as e:
print(e)
f1(1, 2, k1=3, k2=4)
%reset -f
Usando un diccionario es lo mas simple
def switcher(value):
options = {
"val1": 1,
"val2": 2,
"val3": 3,
"val4": 4,
}
if value not in options:
raise ValueError()
return options[value]
print(switcher("val3"))
print(switcher("val1"))
Podemos guardar funciones adentro tambien
def f1(): return 1
def f2(): return 2
def f3(): return 3
def f4(): return 4
def switcher(value):
options = {
"val1": f1,
"val2": f2,
"val3": f3,
"val4": f4,
}
if value not in options:
raise ValueError()
return options[value]
print(switcher("val3")()) # <-- notar el ()
print(switcher("val1")()) # <-- notar el ()
global
¶%reset -f
Esto funciona lo mas bien
def f(a):
print(a)
print(b)
f(10)
Era broma, ahora si
b = 20
def f(a):
print(a)
print(b)
f(10)
Peeero ahora ya no funciona
b = 20
def f(a):
print(a)
print(b)
b = 100
f(10)
??????????????????????
Sucede que tenemos que definir que b
es una variable global si vamos a asignarla
b = 20
def f(a):
global b
print(a)
print(b)
b = 100
f(10)
Pero por que?
%reset -f
b = 20
def f(a):
print(locals())
f(10)
def f(a):
import __main__
print(locals())
print("b in __main__?", "b" in vars(__main__))
__main__.b = 100
f(10)
nonlocal
¶%reset -f
Calculemos el "running average"
def average():
lista = []
def running_avg(value):
lista.append(value)
s = sum(lista)
return float(s)/len(lista)
return running_avg
avg = average()
print(avg(1))
print(avg(5))
print(avg(10))
print(avg(3))
print(avg(50))
Como funciona esto?
Como funciona esto?
print(avg.__code__.co_freevars)
print(avg.__closure__)
print(avg.__closure__[0].cell_contents)
Igual es ineficiente guardar todo el rato la lista...
def average():
suma = 0.
lista = 0
def running_avg(value):
lista += 1
suma += value
return suma/lista
return running_avg
avg = average()
avg(10)
Nos lo echamos otra vez...
Tenemos que usar nonlocal
def average():
suma = 0.
lista = 0
def running_avg(value):
nonlocal suma, lista
lista += 1
suma += value
return suma/lista
return running_avg
avg = average()
print(avg(1))
print(avg(5))
print(avg(10))
print(avg(3))
print(avg(50))
print(avg.__code__.co_freevars)
print(avg.__closure__)
@classmethod
¶def m_clase(cls): pass
def m_static(): pass
def m_instance(self): pass
self
como argumento en la primera posicion. Reciben la instanciacls
como argumento en la primera posicion. Reciben la claseUn ejemplo
%reset -f
class A:
def __init__(self, var1, var2):
self.var1 = var1
self.var2 = var2
def instance_method(self, *args):
print(self)
return self
@classmethod
def class_method(cls, *args):
print(cls)
return cls(*args)
@staticmethod
def static_method(*args):
return A(*args)
a = A(1,2)
a.instance_method(1, 2)
print(a.class_method(1, 2))
print(a.static_method(1, 2))
La diferencia entonces
class B(A): pass
b = B(1,2)
b.instance_method(1, 2)
print(b.class_method(1, 2))
print(b.static_method(1, 2))
dict.fromkeys(iterable, default_value)
d_1 = {
"a": 0,
"b": 0,
"c": 0,
"d": 0,
"e": 0,
}
print(d_1)
d_2 = dict.fromkeys("abcde", 0)
print(d_2)
__dict__
%reset -f
class A:
pass
a = A()
try:
a.variable
except AttributeError as e:
print(e)
a.variable = 150
print(a.variable)
class A:
pass
def f():
print(10)
a = A()
try:
a.f()
except AttributeError as e:
print(e)
a.f = f
a.f()
class A:
pass
def f(self):
print(self)
a = A()
a.f = f
try:
a.f()
except TypeError as e:
print(e)
a.f(100)
La buena forma
import types
a.f = types.MethodType(f, a)
a.f()
%reset -f
def print_function_name(function):
print(function.__name__)
return function
def f():
pass
f = print_function_name(f)
f()
Funciona una pura vez
def print_function_name(function):
def wrapper():
print(function.__name__)
return function
return wrapper
def f():
pass
f = print_function_name(f)
f()
f()
f()
El decorador
@print_function_name
def mi_super_funcion():
pass
mi_super_funcion()
mi_super_funcion()
mi_super_funcion()
def print_args(func):
def wrapper(a):
print(func.__name__, a)
return func(a)
return wrapper
@print_args
def my_name(a):
return a
my_name(100)
La buena forma
def print_args(func):
def wrapper(*args, **kwargs):
print(func.__name__, args, kwargs)
return func(*args, **kwargs)
return wrapper
@print_args
def my_name(a):
return a
my_name(100)
import functools
def print_args(func):
#################
@functools.wraps(func)
#################
def wrapper(*args, **kwargs):
print(func.__name__, args, kwargs)
return func(*args, **kwargs)
return wrapper
def caller(num=10):
def inner_decorator(func):
print(f"Inside inner_decorator with func: {func.__name__}")
@functools.wraps(func)
def decorator(*args, **kwargs):
print(f"Inside decorator with args: {args} {kwargs}")
return func(*args, **kwargs)
return decorator
print(f"Inside caller with arg: {num}")
return inner_decorator
@caller(num=100)
def f(arg1, arg2):
print(arg1, arg2)
f(1,2)
def caller(_func=None, *, num=10):
def inner_decorator(func):
print(f"Inside inner_decorator with func: {func.__name__}")
@functools.wraps(func)
def decorator(*args, **kwargs):
print(f"Inside decorator with args: {args} {kwargs}")
return func(*args, **kwargs)
return decorator
#########################
if _func is None:
print(f"With arguments: {num}")
return inner_decorator
else:
print(f"No arguments, falling to default decorator")
return inner_decorator(_func)
print("F1------")
@caller(num=100)
def f1(arg1, arg2):
print(arg1, arg2)
print("F2------")
@caller
def f2(a,b,arg1=3, arg2=5):
print(a, b, arg1, arg2)
print("F1------")
f1(1,2)
print("F2------")
f2(10,20)
def counter(func):
def wrapper(*args, **kwargs):
wrapper.calls += 1
return func(*args, **kwargs)
wrapper.calls = 0
return wrapper
@counter
def fun(a):
print(a)
for i in range(10):
fun(i)
fun(100)
fun(150)
print(f"Num calls: {fun.calls}")
def decorator(cls):
print(cls)
cls.variable1 = 10
# podria ser una funcion con nombre tambien
setattr(cls, "funcion", lambda self, x: self.variable1 + x)
return cls
@decorator
class A: pass
a = A()
print(a.variable1)
print(a.funcion(100))
class Counter:
def __init__(self, func):
self.calls = 0
self.func = func
functools.update_wrapper(self, func)
def __call__(self, *args, **kwargs):
self.calls += 1
return self.func(*args, **kwargs)
@Counter
def fun(a):
print(a)
for i in range(10):
fun(i)
fun(100)
fun(150)
print(f"Num calls: {fun.calls}")
def singleton(cls):
@functools.wraps(cls)
def wrapper(*args, **kwargs):
if not wrapper.instance:
wrapper.instance = cls(*args, **kwargs)
return wrapper.instance
wrapper.instance = None
return wrapper
class A:
pass
@singleton
class B:
pass
a1 = A()
a2 = A()
b1 = B()
b2 = B()
print(a1 is a2)
print(b1 is b2)
@functools.lru_cache(maxsize=20)
def recursive(num):
print(num)
if num <= 0:
return num
return recursive(num-1)
for i in range(10):
recursive(i)
for _ in range(100):
for i in range(4):
recursive(i)
print(recursive.cache_info())
property
)¶%reset -f
Usando una funcion
class Person:
def __init__(self, name, surname):
self.name = name
self.surname = surname
def get_full_name(self):
return f"{self.name} {self.surname}"
def set_full_name(self, full_name):
self.name, self.surname = full_name.split()
person = Person("JP", "Silva")
print(person.get_full_name())
person.set_full_name("J-P Silva")
print(person.get_full_name())
Pero que lata poner todo el rato getVAR
, setVAR
...
class Person:
def __init__(self, name, surname):
self.name = name
self.surname = surname
def get_full_name(self):
return f"{self.name} {self.surname}"
def set_full_name(self, full_name):
self.name, self.surname = full_name.split()
full_name = property(get_full_name, set_full_name)
person = Person("JP", "Silva")
print(person.full_name)
person.full_name = "J-P Silva"
print(person.full_name)
class Person:
def __init__(self, name, surname):
self.name = name
self.surname = surname
@property
def full_name(self):
return f"{self.name} {self.surname}"
@full_name.setter
def full_name(self, person_name):
self.name, self.surname = person_name.split()
person = Person("JP", "Silva")
print(person.full_name)
person.full_name = "J-P Silva"
print(person.full_name)
class NumberProxy:
def __init__(self, value):
self.value = value
def __get__(self, obj, objtype):
return self.value
class Container:
a = NumberProxy(100)
c = Container()
c.a
%reset -f
Anime
AnimeList
_id_count = 0
class Anime:
def __init__(self, name, ranking):
global _id_count
self.id = _id_count
_id_count += 1
self.name=name
self.ranking = ranking
def is_higher(self, other_anime):
return self.ranking > other_anime.ranking
all_anime = []
for rank, name in enumerate(["FMA", "Steins;Gate", "HxH", "Kimi no Na Wa"]):
all_anime.append(Anime(name=name, ranking=rank))
class AnimeList:
def __init__(self, anime_list=None):
if anime_list is not None:
self.anime_list = anime_list
else:
self.anime_list = []
def add_anime(self, anime):
self.anime_list.append(anime)
def get_all_anime(self):
return self.anime_list
def get_anime(self, indices):
return self.anime_list[indices]
def num_anime(self):
return len(self.anime_list)
anime_list = AnimeList()
for anime in all_anime[1:]:
anime_list.add_anime(anime)
print(anime_list.get_all_anime())
print(anime_list.get_anime(2))
print(anime_list.num_anime())
class Anime:
class Ids:
counter = 0
def __call__(self):
self.counter += 1
return self.counter
id_generator = Ids()
def __init__(self, name, ranking):
self._id = self.id_generator()
self.name=name
self.ranking = ranking
def __eq__(self, other_anime):
return self.name == other_anime.name and self.ranking == other_anime.ranking
def __repr__(self):
return f"(id={self._id}, name={self.name}, rank={self.ranking})"
def __str__(self):
return self.name
all_anime = []
for rank, name in enumerate(["FMA", "Steins;Gate", "HxH", "Kimi no Na Wa"]):
all_anime.append(Anime(name=name, ranking=rank))
class AnimeList:
def __init__(self, anime_list=None):
if anime_list is not None:
self.anime_list = anime_list
else:
self.anime_list = []
def __add__(self, anime):
temp = self.anime_list.copy()
temp.append(anime)
return AnimeList(temp)
def __radd__(self, anime):
temp = self.anime_list.copy()
temp.insert(0, anime)
return AnimeList(temp)
def __eq__(self, other_list):
return self.anime_list == other_list.anime_list
def __getitem__(self, indices):
return self.anime_list[indices]
def __len__(self):
return len(self.anime_list)
def __repr__(self):
return str(self.anime_list)
anime_list = AnimeList()
for anime in all_anime[1:]:
anime_list += anime
print(anime_list)
print(anime_list[:-1])
print(len(anime_list))
anime_list += all_anime[0]
anime_list = all_anime[0] + anime_list
print(anime_list)
from functools import total_ordering
import itertools
@total_ordering
class Anime:
class NewId:
gen = itertools.count()
def __call__(self):
return next(self.gen)
new_id = NewId()
def __init__(self, name, ranking):
self._id = Anime.new_id()
self.name=name
self.ranking = ranking
def __eq__(self, other_anime):
return self.name == other_anime.name and self.ranking == other_anime.ranking
def __hash__(self):
return hash(str(self._id) + self.name)
def __lt__(self, other_anime):
return self.ranking < other_anime.ranking
def __repr__(self):
return f"(id={self._id}, name={self.name}, rank={self.ranking})"
def __str__(self):
return self.name
def __iter__(self):
return iter((self.name, self.ranking))
all_anime = []
for rank, name in enumerate(["FMA", "Steins;Gate", "HxH", "Kimi no Na Wa"]):
all_anime.append(Anime(name=name, ranking=rank))
class AnimeList:
def __init__(self, anime_list=None):
if anime_list is not None:
self.anime_list = anime_list
else:
self.anime_list = []
def __add__(self, anime):
temp = self.anime_list.copy()
temp.append(anime)
return AnimeList(temp)
def __radd__(self, anime):
temp = self.anime_list.copy()
temp.insert(0, anime)
return AnimeList(temp)
def __eq__(self, other_list):
return self.anime_list == other_list.anime_list
def __getitem__(self, indices):
return self.anime_list[indices]
def __len__(self):
return len(self.anime_list)
def __repr__(self):
return str(self.anime_list)
def __contains__(self, anime):
return anime in self.anime_list
def __iter__(self):
return iter(self.anime_list)
anime_list = AnimeList()
for anime in all_anime[1:]:
anime_list += anime
print(anime_list)
print(anime_list[:-1])
print(len(anime_list))
anime_list += all_anime[0]
anime_list = all_anime[0] + anime_list
print(anime_list)
for anime_name, anime_ranking in anime_list:
print(anime_name, anime_ranking)
class A:
def __init__(self, var):
self.var=var
def __eq__(self, other):
print("__eq__ not implemented in A")
return NotImplemented
def __lt__(self, other):
print("__lt__ not implemented in A")
return NotImplemented
class B:
def __init__(self, var):
self.var=var
def __eq__(self, other):
print("__eq__ is implemented in B")
return self.var == other.var
def __gt__(self, other):
print("__gt__ is implemented in B")
return self.var > other.var
a = A(10)
b = B(1)
print(a==b)
b = B(10)
print(a==b)
print("-"*20)
print(a < b)
%reset -f
class A:
def __init__(self, var):
self.var = var
def mA(self):
print("Im in A")
class B(A):
def __init__(self, var1, var2):
super().__init__(var1)
self.var2 = var2
def mB(self):
print("Im in B")
a = A(10)
b = B(100, 200)
print("a is A", isinstance(a, A))
print("a is B", isinstance(a, B))
print("b is A", isinstance(b, A))
print("b is B", isinstance(b, B))
print("Metodos")
b.mA()
b.mB()
print("b variables", b.var, b.var2)
class A:
def m(self):
print("Im in A")
class B(A):
def m(self):
print("Im in B")
class C(B):
def m(self):
print("Im in C")
class D(C):
def m(self):
print("Im in D")
def callerD(self):
self.m()
def callerC(self):
super(D, self).m()
def callerB(self):
super(C, self).m()
def callerA(self):
super(B, self).m()
d = D()
d.callerD()
d.callerC()
d.callerB()
d.callerA()
class Student:
def __init__(self, student_id, school, *args, **kwargs):
self.student_id = student_id
self.school = school
def identification(self):
return f"ID:{self.student_id}-{self.surname}-{self.school}"
class Human:
def __init__(self, name, age, *args, **kwargs):
self.name = name
self.age = age
def identification(self):
return f"{self.name}"
class Yo(Student, Human):
pass
yo = Yo(0, "JP Silva", "UChile", 500)
print(yo.identification())
Method Resolution Order (MRO)
Yo.__mro__
class Yo(Human, Student):
pass
yo = Yo(0, "JP Silva", "UChile", 500)
print(yo.identification())
???????????????????
Probemos otra cosa
class Yo(Human, Student):
def identification(self):
return Human.identification(self)
def school_identification(self):
return Student.identification(self)
yo = Yo(student_id=0, name="JP Silva", school="UChile", age=500)
print(yo.identification())
print(yo.school_identification())
oof que pasa
La buena forma, inicializar a todos los padres manualmente
class Yo(Human, Student):
def __init__(self, name, *args, **kwargs):
Human.__init__(self, *args, name=name, **kwargs)
Student.__init__(self, *args, name=name, **kwargs)
self.surname = name.split()[1]
def identification(self):
return Human.identification(self)
def school_identification(self):
return Student.identification(self)
yo = Yo(student_id=0, name="JP Silva", school="UChile", age=500)
print(yo.identification())
print(yo.school_identification())
class Mixin:
def mixin(self, arg1, arg2):
print(arg1, arg2)
# Mixin no tiene `var`
return self.var
class SuperClass:
def m(self):
print("In SuperClass")
class Example(SuperClass, Mixin):
def __init__(self, var):
self.var = var
e = Example(5)
print(e.mixin(1, 2))
sklearn
esta lleno de Mixins: https://github.com/scikit-learn/scikit-learn/blob/1495f6924/sklearn/base.py#L328Metaclasses are deeper magic than 99% of users should ever worry about. If you wonder whether you need them, you don’t (the people who actually need them know with certainty that they need them, and don’t need an explanation about why)\ -- Tim Peters
%reset -f
Objeto como instancia de una clase
class A:
def __init__(self, var):
self.var = var
a = A("hola")
print(a.var)
a.v1 = 10
print(a.v1)
def example(arg):
print(arg)
example(a)
Las clases tambien son objetos
Clases como objetos
class A:
def __init__(self, var):
self.var = var
print(A)
A.something = 100
print(A.something)
otherA = A
print(otherA.something)
print(otherA("Otra clase"))
Muy util
class_list = []
for i in range(5):
###### Clase dentro? ######
class AClass:
var = i
def __init__(self, arg):
print(arg)
class_list.append(AClass)
print(class_list)
print([c.var for c in class_list])
class_instances = []
for c, arg in zip(class_list, "holaquetal"):
class_instances.append(c(arg))
print(class_instances)
a = A("holi")
print(a)
print(a.__class__)
print(A)
print(A.__class__)
print(a.__class__.__class__)
type
como funcion y como clase?¶print(type(a))
print(type(10))
print(type("Hola"))
print(type(True))
print(type(type(True)))
type(class, bases, dict)
B = type("B", (), {})
print(B)
print(B())
Con variables
C = type("C", (B, A), {"a":1, "b":2})
print(C)
c = C(100)
print(c.__dict__)
variables = []
for member_name in dir(c):
if "__" not in member_name:
value = getattr(c, member_name)
variables.append(f"{member_name}={value}")
print(", ".join(variables))
Con metodos
def m(self, var):
print(self.a, var)
D = type("D", (), {"a":1, "m":m})
d = D()
d.m(100)
type
es una metaclasetype
es super clase de si mismod = D()
print(d.__class__)
print(d.__class__.__class__)
print(d.__class__.__class__.__class__)
dir(d.__class__.__class__)
def all_dunder(cls, bases, attrs):
dunder_attrs = {}
for name, val in attrs.items():
if not name.startswith('__'):
print(f"Replacing {name} with __{name}__")
dunder_attrs[f"__{name}__"] = val
else:
dunder_attrs[name] = val
return type(cls, bases, dunder_attrs)
class AllDunder(metaclass=all_dunder):
def a(arg):
return arg
def b(arg):
return arg
def c(arg):
return arg
dunder = AllDunder()
dir(dunder)
class AllDunder(type):
def __new__(cls, clsname, bases, attrs, **kwargs):
print(kwargs)
dunder_attrs = {}
for name, val in attrs.items():
if not name.startswith('__'):
print(f"Replacing {name} with __{name}__")
dunder_attrs[f"__{name}__"] = val
else:
dunder_attrs[name] = val
return super().__new__(cls, clsname, bases, dunder_attrs)
class AllDunder(metaclass=AllDunder, arg1="do this", arg2="do that"):
def a(arg):
return arg
def b(arg):
return arg
def c(arg):
return arg
class IntContainer:
...
pass
class StrContainer:
...
pass
class FixFields(type):
def fix_complicated_database_logic(new_class, var_name, var_value):
...
def get_prop(self):
return getattr(self, "__" + var_name)
def set_prop(self, value):
return setattr(self, "__" + var_name, value)
# este None es la logica complicada de meterse a la BD
setattr(new_class, "__" + var_name, None)
setattr(new_class, var_name, property(get_prop, set_prop))
def __new__(cls, clsname, bases, attrs, **kwargs):
filter_prop = {}
std_dict = {}
for name, val in attrs.items():
if not name.startswith('__'):
filter_prop[name] = val
else:
std_dict[name] = val
new_cls = super().__new__(cls, clsname, bases, std_dict)
setattr(new_cls, "attributes", set())
for name, val in filter_prop.items():
if not name.startswith('__'):
FixFields.fix_complicated_database_logic(new_cls, name, val)
getattr(new_cls, "attributes").add(name)
setattr(new_cls, "attributes", frozenset(getattr(new_cls, "attributes")))
return new_cls
class Model(metaclass=FixFields):
def __init__(self, **kwargs):
for arg, val in kwargs.items():
setattr(self, arg, val)
class ComplicatedAttrs(Model):
age = IntContainer()
name = StrContainer()
db = ComplicatedAttrs(age=10, name="Hola")
print(db.attributes)
print(f"age = {db.age}")
print(f"name = {db.name}")
db.age=100
print(f"age = {db.age}")
%reset -f
from collections.abc import Sized
class A:
def __len__(self):
return 10
a = A()
print(isinstance(a, Sized))
????????????????????????
dir(Sized)
print(Sized.__abstractmethods__)
import inspect
print(inspect.getsource(Sized.__class__))
%reset -f
__slots__
¶class A:
__slots__ = "a", "b"
def __init__(self, a, b):
self.a = a
self.b = b
class B:
def __init__(self, a, b):
self.a = a
self.b = b
from sys import getsizeof
v = A(10, 20)
print(getsizeof(v.__slots__))
vb = B(10, 20)
print(getsizeof(vb.__dict__))
%reset -f
__class__
¶class Node:
def __init__(self, function):
assert hasattr(function, "__call__")
self.operation = function
self.num_arguments = function.__code__.co_argcount
self.arguments = []
def eval(self):
return self.operation(*[node.eval() for node in self.arguments])
def replace(self, otherNode):
assert isinstance(otherNode, Node)
self.__class__ = otherNode.__class__
self.__dict__ = otherNode.__dict__
class AddNode(Node):
num_args = 2
def __init__(self, left, right):
super(AddNode, self).__init__(lambda x,y: x+y)
self.arguments.append(left)
self.arguments.append(right)
def __repr__(self):
return "({} + {})".format(*self.arguments)
class TerminalNode(Node):
num_args = 0
def __init__(self, value):
super(TerminalNode, self).__init__(lambda:None)
self.value = value
def __repr__(self):
return str(self.value)
def eval(self):
return self.value
n = AddNode(TerminalNode(1), TerminalNode(2))
print(f"n: {n}=", n.eval())
print(isinstance(n, AddNode))
n.replace(TerminalNode(200))
print(f"n: {n}=", n.eval())
print(isinstance(n, AddNode))
print(isinstance(n, TerminalNode))
El error
def f(value, a=[]):
a.append(value)
...
return sum(a)
returns = []
for i in range(10):
returns.append(f(i))
print(returns)
print(f.__defaults__)
La solucion
def f(value, a=None):
if a is None:
a = []
a.append(value)
...
return sum(a)
returns = []
for i in range(10):
returns.append(f(i))
print(returns)
print(f.__defaults__)
257
no es 257
?¶%reset -f
a=1
b=1
print(a is b)
a=257
b=257
print(a is b)
row = [""]*3
print(row)
board = [row]*3
print(board)
board[0][1] = "X"
print(board)
def f(n):
res = []
for x in range(n):
def aux():
return x + 10
res.append(aux)
return res
partial_fns = f(10)
print(partial_fns)
print([fn() for fn in partial_fns])
def f(n):
res = []
for x in range(n):
##########.###########
def aux(x=x):
return x + 10
res.append(aux)
return res
partial_fns = f(10)
print(partial_fns)
print([fn() for fn in partial_fns])