Очаровательный Python 1 Владислав Ананьев Смоленск, 2013 Smolensk Computer Science Club
Очаровательный Python
1
Владислав Ананьев
Смоленск, 2013
Smolensk Computer Science Club
importimport thisthis
Cpython
PyPyJython
IronPythonStackless
структурное
функциональное
Объектно-ориентированное
аспектно-ориентированное
императивное
объектно-ориентированный
кроссплатформенный
императивный
рефлективный
функциональный
аспектно-ориентированный
мультипарадигменный
динамическая типизация
высокоуровневые структуры
механизм обработки
исключений
поддержка многопоточных
вычислений
полная интроспекция
Введение
Guido van Rossum
2
Кому он нужен ?Кому он нужен ?
IT — компании, использующие Python3
О типах и структурах...О типах и структурах...
объекты Python
атомарные (int, long, complex)
ссылочные
изменяемые (mutable)
неизменяемые (immutable)
Типы и структуры Python
str "Hello, world!" immutable [2:6], find(), replace(),split(), encode(), startswith() и т.п.
list [1,2,3,4,5] mutable len(), in, not in, +, *, i[i] =m, append(x), count(x), extends, pop()
dict {'a':1, 'b':2} mutable Len(), h1.update(h3),
tuple (1,2,3,4,5) immutable count(), index()
a,b,c,d,e = 1,2,3,4,5
t = 1,2,4
4
Базовый синтаксисБазовый синтаксисlist = [1, 2, 3, 'Вася Пупкин', 5]dict = {'a':1, 'meaning':42}tuple = ('spam', 42, 1337)startWord = 'spam'meaningOfLife = 42a, b = 2, 42
присваивание
list = [1,2,3,4,5]for x in list: print x
Цикл for
tuple = ('a', 'b', 'c', 'd')if 'a' in tuple: print ' "a" in tuple'else: print ' "b" not in tuple'
условие
Базовый синтаксис
L = [x**2 for x in range(10)]
L1 = [x**2 for x in range(10) if x%2 != 0]
List comprehensions
s = [1,2,3,4,6]s1 = s[:]s2 = s[1:]s3 = s[:-2] # последние 2 элемента
s4 = s[1:4:2] # элементы 1-4 с шагом 2for i, x in enumerate(range(1,10,2)): print i, x
Распаковка кортежа for (ip, port) in connections: if port < 1024: print 'Connected to %s on %s' % (ip, port)
Цикл for со счетчиком i
«Слайсирование»
ingredients = ['bacon', 'sausages', 'spam', 'spam']print 'Ingredients are: %s.' % ', '.join(ingredients)
Вывод списка
5
Duck TypingDuck Typing
«Если это выглядит как утка, плавает как утка и крякает как утка, то, вероятно, это утка».
def IsMappingType(obj, require_set=False):
if require_set and not hasattr(obj, '__setitem__'): return False if hasattr(obj, 'keys') and hasattr(obj, '__getitem__'): return True else: return False
def IsSequenceType(obj, require_set=False):
if require_set and not hasattr(obj, '__setitem__'): return False if (not hasattr(obj, 'keys')) and hasattr(obj, '__getitem__'): return True else: return False
Утиная типизация
list = [2,2,2,2,3]string = "Hello, i'm a simple strring"dict = {'a':1,'b':2,'c':3}
print IsMappingType(dict, require_set=True)print IsSequenceType(list, require_set=True)print IsSequenceType(string)
TrueTrueTrue
f = open(filename)for char in f.read():
process(char)
6
try: import ololoexcept ImportError as e: print "cannot import rquired module, exception message is: %s" % e.message
ИсключенияИсключения
Исключения в Python
try: import urllibexcept ImportError: import urllib2
try: f = open('somefile') s = f.readline() i = int(s.strip())except IOError as e: print "Ошибка ввод/вывода", eexcept ValueError: print "Не удается преобразовать данные к целому типу"except: print "Внезапная неизвестная ошибка" raise
7
Функция в PythonФункция в Python
def dummyFunct(): pass
def sumOfSquares(a, b): """calculates a sum of two squares""" return a**2 + b**2
docstring
def gcd(a, b): """evaluates a gcd""" while a != 0: a,b = b%a,a return b
Парное определение
myGCD = gcd(1878, 689334) #6print gcd.__doc__ # evaluate a gcd
def spam(a, b, c = 0): return a + b + c
c задан по умолчанию
Функция в Python8
Функция в Python. Position и keyword аргументы
Position и keywordPosition и keyword аргументы аргументы
def calculateSumOfArgs(*args): sum = 0 for arg in args: sum += arg return sum
print calculateSumOfArgs(42,444,555,666,32)
position аргумент
def listArgs(farg, *args): print "formal arg:", farg for arg in args: print "position arg:", arg
listArgs (1,2,3,4)
def listArgs(farg, *args): print "formal arg:", farg for i, arg in enumerate(args): print "position arg %i: %s" % (i, arg)
listArgs (1,2,3,4)
>>>formal arg: 1another arg: 2another arg: 3another arg: 4
>>>formal arg: 1position arg 0: 2position arg 1: 3position arg 2: 4
9
def generateInsertStatement(table, **kwargs):"""Generates Database insert statement""" cols = [] vals = []
for col, val in kwargs.items(): cols.append(col.replace("'", r"\'")) vals.append("'%s'" % (str(val)).replace('"', r'\"')) cols = ", ".join(cols) vals = ", ".join(vals)
return 'INSERT INTO %s(%s) VALUES(%s);' % ( table, cols, vals)
keyword аргумент
print generateInsertStatement("Person", name="John", surname= "Smith", career = "agent")
params = {"name": "Thomas", "surname" :"Anderson", "career": "hacker"}print generateInsertStatement("workers", **params)
>>> INSERT INTO Person(career, surname, name) VALUES('agent', 'Smith', 'John')INSERT INTO workers(career, surname, name) VALUES('hacker', 'Anderson', 'Thomas')
Функция в Python. Position и keyword аргументы
Position и keywordPosition и keyword аргументы аргументы
10
Функция в Python — объект 1 классаФункция в Python — объект 1 класса
Функция в Python — объект 1 класса
def testSort(lst): if lst: return testSort([elem for elem in lst[1:] if elem<lst[0]]) + lst[0:1] + testSort([elem for elem in lst[1:] if elem>=lst[0]]) return []
- может быть сохранен в переменной или структурах данных - может быть передан в функцию как аргумент - может быть возвращен из функции как результат - может быть создан во время выполнения программы - внутренне самоидентифицируем (независим от именования)
func = testSort
lst = [1, 2, 33, 3, 4, 6, 7, 788, 9, 5, 33, 222]
sortedList = func(lst)print sortedList
>>> [1, 2, 3, 4, 5, 6, 7, 9, 33, 33, 222, 788]
теперь func — функция сортировки
11
Передача функции в качестве аргументаПередача функции в качестве аргумента
def fibRec(n): if n == 0: return 0 elif n < 3: return 1 return fibRec(n-1) + fibRec(n-2)
def fibIter(n): a, b = 0, 1 for i in range(n): a, b = b, a + b return a
Передача функции в качестве аргумента12
Передача функции в качестве аргументаПередача функции в качестве аргумента
import time
def timeLogging(func, *args, **kwargs): t = time.time() ret = func(*args, **kwargs) print 'Calling: %s, returned %r elapsed time %f'
% (func.__name__, res, time.time()-t) return ret
функция-параметр
timeLogging(fibRec, 45)timeLogging(fibIter, 45)
передается сама функция, а не результат ее работы
Передача функции в качестве аргумента
>>Calling: fibRec, returned 102334155 elapsed time 28.392000Calling: fibIter, returned 102334155 elapsed time 0.000120
13
Возврат функции в качестве результатаВозврат функции в качестве результата
def fSelector(selector): if selector < 0: def fSqr(x): return x * x return fSqr else: def fCube(x): return x * x * x return fCube
def operate(L, function): res = [function (elem) for elem in L] return res
L = [1, 2, 3, 100]print operate(L, fSelector(1))
>>>[1, 8, 27, 1000000]
Возврат функции в качестве результата
возврат самой функции
14
Определение функции с помощью lambda-выраженияОпределение функции с помощью lambda-выражения
Функция в Python
print (lambda x: x * x)(5)
def fSelector(selector): if selector < 0: return lambda(x): x * x else: return lambda(x): x * x * x
функцию можно вызвать сразу после определения
def operate(L, function): res = [function (elem) for elem in L] return res
>>>[1, 4, 9, 10000]
L = [1, 2, 3, 100]print operate(L, fSelector(-1))
15
ЗамыканиеЗамыкание
Функция в Python. Замыкание
def simpleClosure(targetMaker): def multilpier(arg): return targetMaker * arg return multilpier
targetFunction = simpleClosure(10)
print targetFunction(5)
«захват» переменной targetMakerиз внешнего контекста
simpleClosure = lambda targetMaker: ( lambda arg: ( targetMaker * arg ))
16
КаррированиеКаррирование
Функция в Python. Каррирование
def curryFunction( x ) : def summ( y ) : return x + y return summ
print curryFunction(4)(2)
curryFunction = lambda x: lambda y: x + y
def processingFunction(x, y): return x + y
def curryFunction(x): return lambda(y): processingFunction(x, y)
curryFunction = lambda(x): lambda(y): processingFunction(x,y)
print curryFunction(4)(2)
17
map, reduce, filter...map, reduce, filter...
ФП в Python. Map, Reduce, Filter
L1 = [1, 2, 3, 4, 5, 22, 2]L2 = [-2, 1, 3, 3, -6, 2, 33]L3 = [2, 3, 3, 4, 5, 6, 7]
print map(lambda x, y, z : x + y + z, L1, L2, L3)
L = [4 , 5, 5, 6, 8, 2, 1, 3]print reduce(lambda acml, val: acml * val, L, 1)
listToFilter = [22, 55, 33, 2, 4, 12, 3, 4]print filter(lambda x: x % 2 == 0, listToFilter)
((((((((1 * 4) * 5) * 5) * 6) * 8) * 2) * 1) * 3)
>>>[1, 6, 9, 11, 4, 30, 42]
>>>28800
>>>[22, 2, 4, 12, 4]
18
@ декораторы@ декораторы
Декораторы Python
import time
def timeLogger(function): def decor(*args, **kwargs): t = time.time() res = function(*args, **kwargs) print u'Returned %r elapsed time %f' % (res, time.time()-t) return res return decor
@timeLoggerdef factorial(n): return reduce(lambda x,y:x*y,[1]+range(1,n+1))
factorial(38)
>>>Returned 523022617466601111760007224100074291200000000L elapsed time 0.000020
19
import threading
class Thread(threading.Thread): def __init__(self, f): threading.Thread.__init__(self) self.run = f
@ декораторы@ декораторы
Декораторы Python
@Threaddef runOnOtherwiseThread():
# do something...#
runOnOtherwiseThread.start()
20
Классы в PythonКлассы в Python
ООП в Python. Классы
class Dummy(object): """ This is the class example """ def __init__(self, arg): self._arg = arg
def method(self, x): pass
def _privatemethod(self, x): pass
@staticmethod def static(arg1, arg2, *args, **kwargs): pass
@classmethod def classmethod(cls, arg1, arg2, *args, **kwargs): pass
конструктор
метод
приватный метод
статический метод
метод класса
myinstance = Dummy(4)
21
Классы в PythonКлассы в Python
ООП в Python. Классы
class Employee(object): """ Common Employee """ empCount = 0 def __init__(self, id, name, salary): self.id = id self.name = name self._salary = salary Employee.empCount += 1
@property def salary(self): return self._salary
@salary.setter def salary(self, value): self._salary = value
@staticmethod def getCount(): return Employee.empCount
def __str__(self): return u"id = " + unicode(self.id) + u", Name : " + unicode(self.name) + u", Salary: " + unicode(self.salary)
emp1 = Employee(1, "Thomas Anderson", 250)emp1.salary = 1000emp2 = Employee(2, "John Smith", 2500)
print emp1print emp2print "Total Employee %d" % Employee.getCount()
свойство
вызов метода str
вызов статического метода
>>>id = 1, Name : Thomas Anderson, Salary: 1000id = 2, Name : John Smith, Salary: 2500Total Employee 2
22
НаследованиеНаследование
ООП в Python. Наследование
class Manager(Employee): def __init__(self, id, name, salary, inferiorsCount = 0): super(Manager, self).__init__(id, name, salary) self.__inferiorsCount = inferiorsCount
inferiors = property(lambda self: self.__inferiorsCount)
@inferiors.setter def inferiors(self, value): self.__inferiorsCount = value
def __str__(self): return u"id = %d, Name : %s, Salary: %.2f and has %d inferiors" % (self.id, self.name, self.salary, self.inferiors)
manager = Manager(3, "Trinity Ololo", 1150)manager.salary = 2000manager.inferiors = 2
print managerprint "Total Employee %d" % Employee.getCount()
>>>id = 3, Name : Trinity Ololo, Salary: 2000.00 and has 2 inferiorsTotal Employee 3
23
ПолиморфизмПолиморфизм
class Parent(object): def whoAmI(self) : return 'parent'
class Child(Parent): def whoAmI(self): return 'child'
x = Parent()print x.whoAmI()
y = Child()print y.whoAmI()y.__class__ = Parentprint y.whoAmI()
ООП в Python. Полиморфизм
>>>parentchildparent
24
class Abstract(object):
def abstractMethod(self): raise NotImplementedError('Method is pure virtual')
Абстрактные методыАбстрактные методы
a = Abstract()a.abstractMethod()
>>> raise NotImplementedError('Method is pure virtual')NotImplementedError: Method is pure virtual
ООП в Python. Абстрактные методы25
ИтераторыИтераторы
Итераторы Python
list = [1, 2, 3]for i in list : print(i)
it = iter(sequence)
while True: try: value = it.next() except StopIteration: break print value
26
ИтераторыИтераторы
Итераторы Python
class Reverse(object): 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("Test")rev.next() # trev.next() # s
for x in Reverse("string"): print x
возвращает ссылку на итерируемый объект
возвращает ссылку на следующий элемент или
StopIteration
27
ГенераторыГенераторы
Генераторы Python
def gGenerator(): lst = range(20) for elem in lst: yield elem * elem
generator = gGenerator()print generator
<generator object gGenerator at 0x024BCB48>
возвращает объект-генератор
PEP 255
for sqm in generator: print sqm
28
ГенераторыГенераторы
Генераторы Python
def aCube(n): return n * n * n
def genMap(func, iterable): for item in iterable: yield func(item)
def mymap(func, iterable): return list(genMap(func, iterable))
lst = [1,2,2,3,4]l = mymap(iterable=lst, func=aCube)
def fibonacci(): a, b = 0, 1 while 1: yield a a, b = b, a + b
29
Класс — это объектКласс — это объект
ООП в Python. Класс — это объект
- можно присвоить переменной - можно скопировать - можно добавить к нему атрибут - можно передать функции в качестве аргумента
class ObjectCreator(object): pass
myObject = ObjectCreator()print myObject
<<<<__main__.ObjectCreator object at 0x01EAC910><class '__main__.ObjectCreator'>
MyObjectсам может создавать
объекты (экземпляры), а значит сам является классом
print type(myObject)
30
Динамическое создание классаДинамическое создание класса
ООП в Python. Динамическое создание класса
def classSelector(className): if className == 'spam': class Spam(object): pass return Spam else: class Sausage(object): pass return Sausage
Selected = classSelector('spam')pieceOfSpam = Selected()
>>><class '__main__.Spam'><__main__.Spam object at 0x01FCE5B0>
возвращает сам класс, а не экземпляр
31
Динамическое создание классаДинамическое создание класса
ООП в Python. Динамическое создание класса
def echo(self): print self.attribute
Spam = type('Spam', (), {'attribute': True, 'echo':echo})
spamObject = Spam()
print spamObjectspamObject.echo()
>>><__main__.Spam object at 0x020BE730>True
32
МетаклассыМетаклассы
ООП в Python. Метаклассы
Метакласс — это то, что создает объекты - классы
class someClass(object): __metaclass__ = ...
class Child(Base): pass
Есть ли у класса Childатрибут __metaclass__ ?
Есть ли у класса Baseатрибут __metaclass__ ?
true создание объекта - класса Child
trueсоздание объекта -
класса Child
Поиск __metaclass__в модуле
создание объекта - класса Child
true
Использование type() создание объекта - класса Child
33
МетаклассыМетаклассы
ООП в Python. Метаклассы
class Meta(type): def __new__(cls, name, bases, classDict): return super(Meta,cls).__new__(cls, name, bases, classDict)
def getName(cls): return cls.__name__
def echo(self): print self.attribute
spamClass = Meta('Spam', (), {'attribute': True, 'echo':echo})
spamObject = spamClass()print spamClass.getName()
>>>Spam
34
class Singleton(object): obj = None def __new__(cls,*args,**kwargs): if cls.obj is None: cls.obj = object.__new__(cls,*args,**kwargs) return cls.obj
МетаклассыМетаклассы
ООП в Python. Метаклассы
o1 = Singleton()o2 = Singleton()
print o1 is o2
>>True
35
Пару слов о менеджерах контекстаПару слов о менеджерах контекста
Менеджеры контекста
with open("infile.txt", "r") as file: print file.read() # в случае исключения произойдет закрытие файла
def __enter__(self): return self
def __exit__(self, type, value, tb): self.stream.close()
with DatabaseConnection() as mydbconn:# что-то делаем с БД
36
«Батарейки в комплекте»«Батарейки в комплекте»
Matplotlib — визуализация данных двумерной (2D) и трехмерной (3D) графикойDjango — фреймворк для веб-приложенийPyBrain — библиотека для работы с нейронными сетями и ИИNumPy — библиотека высокоуровневых математических функцийSciPy — открытая библиотека высококачественных научных инструментовPyGame — набор модулей, предназначенный для написания компьютерных игрPyQt — набор «привязок» графического фреймворка Qt
веб — urllib2, httplib, cookielib...алгоритмы — collections, re, difflib, itertools, queue, heap …ОC — windows , posix, argparse, macOS, logging..тестирование и отладка — unittest, doctest, pdb, ipdb, hotshot...
Модули и библиотеки Python37
Редакторы / IDEРедакторы / IDE
Редакторы и IDE для Python
PyCharm $99(30 days trial)
PyScripter Free
Sublime Text 2 $70/ Free
Ninja IDE Opensource
38
Вопросы ?Вопросы ?
39