Objetos#

  • Última modificación: Mayo 13, 2022

[1]:
def scope_test():
    def do_local():
        spam = "local spam"

    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"

    def do_global():
        global spam
        spam = "global spam"

    spam = "test spam"

    do_local()

    print("After local assignment:", spam)

    do_nonlocal()

    print("After nonlocal assignment:", spam)

    do_global()

    print("After global assignment:", spam)


scope_test()
print("In global scope:", spam)
After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

Clases#

[2]:
class MyClass:
    """A simple example class"""

    i = 12345

    def f(self):
        return "hello world"


x = MyClass()
y = MyClass()
[3]:
x
[3]:
<__main__.MyClass at 0x7f6c9e058790>
[4]:
y
[4]:
<__main__.MyClass at 0x7f6c9e058640>
[5]:
x.i
[5]:
12345
[6]:
y.i = 654321
x.i
[6]:
12345
[7]:
y.i
[7]:
654321
[8]:
class Complex:
    def __init__(self, realpart, imagpart):
        self.r = realpart
        self.i = imagpart


x = Complex(3.0, -4.5)
x.r, x.i
[8]:
(3.0, -4.5)

Variables de instancia y de clase#

[9]:
class Dog:

    kind = "canine"  # class variable shared by all instances

    def __init__(self, name):
        self.name = name  # instance variable unique to each instance


d = Dog("Fido")
e = Dog("Buddy")
d.kind  # shared by all dogs
[9]:
'canine'
[10]:
e.kind  # shared by all dogs
[10]:
'canine'
[11]:
d.name  # unique to d
[11]:
'Fido'
[12]:
e.name  # unique to e
[12]:
'Buddy'
[13]:
#
# Construcción errónea
#
class Dog:

    tricks = []  # mistaken use of a class variable

    def __init__(self, name):
        self.name = name

    def add_trick(self, trick):
        self.tricks.append(trick)


d = Dog("Fido")
e = Dog("Buddy")
d.add_trick("roll over")
e.add_trick("play dead")
d.tricks  # unexpectedly shared by all dogs
[13]:
['roll over', 'play dead']
[14]:
#
# Construcción correcta
#
class Dog:
    def __init__(self, name):
        self.name = name
        self.tricks = []  # creates a new empty list for each dog

    def add_trick(self, trick):
        self.tricks.append(trick)


d = Dog("Fido")
e = Dog("Buddy")
d.add_trick("roll over")
e.add_trick("play dead")
d.tricks
[14]:
['roll over']
[15]:
e.tricks
[15]:
['play dead']
[16]:
class Warehouse:
    purpose = "storage"
    region = "west"


#
# Se prioriza la instancia sobre la clase
#
w1 = Warehouse()
print(w1.purpose, w1.region)
storage west
[17]:
w2 = Warehouse()
w2.region = "east"
print(w2.purpose, w2.region)
storage east
[18]:
print(w1.purpose, w1.region)
storage west
[19]:
#
# Un método puede llamar a otro
#
class Bag:
    def __init__(self):
        self.data = []

    def add(self, x):
        self.data.append(x)

    def addtwice(self, x):
        self.add(x)
        self.add(x)

Herencia#

class DerivedClassName(BaseClassName):
    <statement-1>
    .
    .
    .
    <statement-N>
class DerivedClassName(modname.BaseClassName):
    ...

Herencia múltiple:

class DerivedClassName(Base1, Base2, Base3):
    <statement-1>
    .
    .
    .
    <statement-N>

Variables privadas#

Nombres con un subrayado se deben tratar como no públicos

class Mapping:
    def __init__(self, iterable):
        self.items_list = []
        self.__update(iterable)

    def update(self, iterable):
        for item in iterable:
            self.items_list.append(item)

    __update = update   # private copy of original update() method

class MappingSubclass(Mapping):

    def update(self, keys, values):
        # provides new signature for update()
        # but does not break __init__()
        for item in zip(keys, values):
            self.items_list.append(item)

Se reemplaza __update por _Mapping__update

Estructuras#

[20]:
class Employee:
    pass


john = Employee()  # Create an empty employee record

# Fill the fields of the record
john.name = "John Doe"
john.dept = "computer lab"
john.salary = 1000

Iteradores#

[21]:
for element in [1, 2, 3]:
    print(element)
1
2
3
[22]:
for element in (1, 2, 3):
    print(element)
1
2
3
[23]:
for key in {'one':1, 'two':2}:
    print(key)
one
two
[24]:
for char in "123":
    print(char)
1
2
3
[25]:
s = 'abc'
it = iter(s)
it
[25]:
<str_iterator at 0x7f6c9c7ce250>
[26]:
next(it)
[26]:
'a'
[27]:
next(it)
[27]:
'b'
[28]:
next(it)
[28]:
'c'
[29]:
class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)

    def __iter__(self):
        return self

    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]


rev = Reverse('spam')
for char in rev:
    print(char)
m
a
p
s

Generadores#

[30]:
def reverse(data):
    for index in range(len(data) - 1, -1, -1):
        yield data[index]


for char in reverse("golf"):
    print(char)
f
l
o
g