02. Обекти и функции

02. Обекти и функции

02. Обекти и функции

4 март 2013

За обектите

... за тях след малко. Преди това.

Константи

Хубаво е данни които сте сигурни че са константни и няма да се променятда ги изнасяте извън функциите и да ги именовате С_ГЛАВНИ_БУКВИ_И_ДОЛНИ_ЧЕРТИ

def what_is_my_sign(day, month):
days_and_signs = [
{(1, 20): 'Козирог', (20, 32): 'Водолей'},
{(1, 19): 'Водолей', (19, 30): 'Риби'},
{(1, 21): 'Риби', (21, 32): 'Овен'},
{(1, 21): 'Овен', (21, 31): 'Телец'},
{(1, 21): 'Телец', (21, 32): 'Близнаци'},
{(1, 21): 'Близнаци', (21, 31): 'Рак'},
{(1, 22): 'Рак', (22, 32): 'Лъв'},
{(1, 23): 'Лъв', (23, 32): 'Дева'},
{(1, 23): 'Дева', (23, 31): 'Везни'},
{(1, 23): 'Везни', (23, 32): 'Скорпион'},
{(1, 22): 'Скорпион', (22, 31): 'Стрелец'},
{(1, 22): 'Стрелец', (22, 32): 'Козирог'}
]
for key in days_and_signs[month - 1]:
if day in range(*key):
return days_and_signs[month - 1][key]

За обектите

за тях след малко. Преди това.

Въпрос

Какво ще изведе следният код:

'hello'[:2]

Въпрос

Какво ще изведе следният код:

1, 2 is 1, 2

Въпрос

Какво ще изведе следният код:

type({1, 2, 3, 4, 5})

За обектите...

Класове 101

class Person:
    first_name = "Кънчо"
    last_name = "Кънчев"

    def name(self):
        return "{} {}".format(self.first_name, self.last_name)

Конструктор

class Person:
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name

Какъв е този `self`?

Защо self трябва да е експлицитен?

Какво ще се случи тук?

Искаме да можем да кажем на колко години ще е Кънчо през еди-коя-си година

class Person:
    def __init__(self, first_name, last_name, birth_year):
        self.first_name = first_name
        self.last_name = last_name
        self.birth_year = birth_year

    def name(self):
        return "{} {}".format(self.first_name, self.last_name)

    def age_at(year):
        return year - self.birth_year

kuncho = Person('Кънчо', 'Кънчев', 1964)
kuncho.age_at(2060) # Следващият апокалипсис, според Нютон

Показвали ли сме ви как да сравнявате обекти?

>>> a = ['spam', 'eggs', 42]
>>> b = ['spam', 'eggs', 42]

>>> a is b
False
>>> a == b
True

>>> c = a
>>> a == c
True
>>> a is c
True

Дъндъри

Всеки обект в езика има по няколко такива.

__class__         __delattr__       __dict__          __dir__
__eq__            __format__        __ge__            __getattribute__
__hash__          __init__          __le__            __lt__
__ne__            __new__           __qualname__      __reduce__
__repr__          __setattr__       __sizeof__        __str__
__weakref__       __doc__           __gt__            __module__
__reduce_ex__     __reduce_ex__     __subclasshook__ 

Държанието на == може да се промени

def __eq__(self, other):
    return [self.first_name, self.last_name] == [other.first_name, other.last_name]

Други методи за сравнение на обекти

__lt__(self, other)  # self < other
__le__(self, other)  # self <= other
__gt__(self, other)  # self > other
__ge__(self, other)  # self >= other

Аритметични оператори

__add__(self, other)  # self + other
__sub__(self, other)  # self - other
__mul__(self, other)  # self * other
__truediv__(self, other)  # self / other
__floordiv__(self, other)  # self // other
__mod__(self, other)  # self % other
__lshift__(self, other)  # self << other
__rshift__(self, other)  # self >> other
__and__(self, other)  # self & other
__xor__(self, other)  # self ^ other
__or__(self, other)  # self | other

Преобразуване до стандартни типове

__int__(self)  # int(обект)
__float__(self)  # float(обект)
__complex__(self)  # complex(обект)
__bool__(self)  # bool(обект)

Колекции

Python ви предлага и оператори, с които можете да третирате вашия клас като колекция:

__len__(self)  # len(обект)
__getitem__(self, key)  # обект[key]
__setitem__(self, key, value)  # обект[key] = value
__delitem__(self, key)  # del обект[key]
__contains__(self, item)  # item in обект

Lambda функции

Съкратен синтаксис за създаване на функции, с някои сериозни ограничения

def squared(n):
    return n**2

е същото като

squared = lambda n: n**2

Могат да се използват и повече аргументи

power = lambda base, exp: base**exp

Най-полезни са когато се налага да се подаде функция като аргумент

>>> map(lambda n: n**2, [0, 1, 2, 3, 4, 5])
[0, 1, 4, 9, 16, 25]

Могат и да се използват директно в списъци и речници

>>> actions = [lambda n: n**2, lambda n: n**3, lambda n: n**4]
>>> for f in actions:
...    print(f(2))
4
8
16

Можете да използвате тернарният оператор:

>> lower = lambda x, y: x if x < y else y
>> lower("Aa", "Bb")
'Aa'
>> lower("Bb", "Aa")
'Aa'

Ламбдите могат да се извикват и веднага след като се създадат:

>>> for line, n in [("Who let the dogs out?", 1), ("Who?", 4)]:
...  (lambda a, b: print(a*b))(line, n)
...
'Who let the dogs out?'
'Who?Who?Who?Who?'

Ограничения

Това означава че НЕ МОЖЕ

Въпроси?