Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 www.iakovlev.org 

 

Python

Основные особенности питона ? Встроенные типы данных ? Как используются глобальные переменные внутри функции ? Приведите пример вложенной функции . Какой метод используется для копирования обьекта ? Что такое namespace ? Что такое self ? Что такое интроспекция ? Можно в питоне создать перегруженный конструктор ? Инструменты тестирования в питоне - Quality control ? Назовите статические анализаторы исходников ? Как запустить sub-процесс и отловить его вывод ? Что такое lambda ? Для чего нужен assert ? Как передать произвольный список параметров в функцию ? Что такое пакет ? Как в питоне создать структуру данных ? Как создать поток ? Регулярные выражения ? Что такое sequence unpacking ( iterable unpacking). ? Что такое декоратор ? Что такое super ? Что такое shared references ? Менеджер контекста with ? Профилирование кода ? Модули Что такое модуль ? Стандартные модули ? Для чего нужен модуль Pickle ? Как расшарить глобальную переменную для нескольких модулей ? Как работает модуль bisect ? Модуль subprocess ? Классы Что такое класс ? Как проверить , является ли обьект инстансом данного класса ? Как вызвать перегруженный метод базового класса ? Private для класса ? Специальные встроенные методы классов ? Property для классов ? Singleton pattern ? Полифморфизм ? Что такое абстрактный суперкласс ? Фабрика обьектов ? Методы: bound и unbound ? Diamond inheritance ? Слоты ? Статические методы и методы класса ? Functor ? Дескрипторы ? Файлы Как удалить , скопировать файл ? Как распечатать содержимое всего файла ? Распечатать все файлы с расширением *.py в каталоге , имеющем вложенные каталоги ? Стандартный ввод-вывод ?

Типы данных

Списки Операции со списком : как найти элемент , вставить элемент в середину списка , в конец , удалить по индексу , перевернуть список , отсортировать список ? Что такое tuple ? Встроенные функции списка : filter , map , reduce ? Использование списков в качестве стека , очереди Прямая и обратная индексация ? Как сделать реверс списка ? Обьединить 2 списка и отсортировать Напишите программу , которая сконвертирует список числовых строк в список чисел Напишите программу , которая удалит из списка все значения , меньше 10 ? Напишите функцию , которая удаляет дубли из списка Как создать много-мерный список ? Найти 2 минимума в не-отсортированном списке ? Словари Что такое словарь ? Методы keys() , values() , items() , has_key() , iterkeys() , itervalues() , iteritems() ? Методы clear(), update(), get(), popitem(), pop() ? Когда нужно использовать словари , когда - списки ? Как с помощью dict() можно сгенерировать словарь ? Строки Встроенные строковые методы ? Как из бинарной строки прочитать 2-байтовое целое и 4-байтовое целое ? Как сгенерировать юникодную строку ? Напишите функцию , удаляющую пробелы из строки Network Написать простой сервер на базе модуля socket ? Написать простой сервер на базе twisted ? Написать простой сервер на базе модуля SocketServer ? Web Как сделать программно web-POST ? Как работать с куками ? Как получить информацию по адресу страницы ? Получить файл по ftp ?

Какие методы используются для прохода по коллекциям разного типа ? Что такое сеты ? Реализовать итератор на основе класса Приведите пример генератора Как работает обьект array ? Как работает обьект deque ? Написать функцию , выполняющую те же действия , что и команда tail -f logfile ? Напишите функцию , делающую своп 2-х чисел Написать рекурсивную функцию для вычисления факториала

Ответы

   0 Интерпретируемый высоко-уровневый язык
   1 Большой набор типов данных : списки , словари 
   2 Классы с множественным наследованием
   3 Разбиение кода на модули и пакеты
   4 Обработка исключений
   5 GC (garbage collector) 
 
Питон имеет динамическую типизацию. Классы могут обьединяться в модули , модули могут обьединяться в пакеты .

 Если внутри функции есть переменная , которая перекрывает по имени внешнюю , 
 то последняя будет не видна . Для создания ее глобальной видимости внутри функции ее нужно обьявить
 как :
     global var
 
 

 Ее нужно вынести в отдельный модуль , а потот этот модуль импортировать :
 config.py:
   x=0
   ...
 mod.py
   import config
   print config.x
 
 

 def linear(a,b):
     def result(x):
       return a*x + b
     return result
 

 copy()
 Например , копирование словаря :
   olddict={1:11,2:22}
   newdict = olddict.copy() 
   print newdict
 

 namespace - это пространство имен. Примером могут служить :
   встроенные функции типа abs()
   глобальные переменные модуля
   локальные переменные функции
 Между ними совершенно нет никакой связи . 
 Время жизни у разных нйм-спэйсов разное - первый живет все время , пока работает интерпретатор ,
 второй - пока загружен модуль , третий - на время работы функции . 
   
 
 

 Тип обьекта с одноименным названием .
 В свою очередь , может иметь несколько базовых классов , наследуя их атрибуты и методы .
 Обьекты класса поддерживают 2 типа операций :
   ссылка на атрибут
   инстанциация
 Примером ссылки на атрибут может служить
   MyClass.i 
   MyClass.f
 или
   MyClass.i = 10
 Инстанциация - это создание обьекта класса :
   x = MyClass()
 Обьект в свою очередь может делать ссылки на свои атрибуты.
 
 Для питона есть правило : если в классе есть данные и метод с одним названием , то данные перекроют метод.
 В классе можно определить private атрибут - он должен начинаться с двойного префикса __ .
 
 
 
 
 
 

 Это имя первого аргумента в методе , внутри класса это фактически обьект самого класса .
 

 Introspection - способность определить тип обьекта в ран-тайме.
 
 dir(object)  - возвращает отсортированный список атрибутов и методов обьекта
 type(object) - возвращает тип обьекта
 id(object)   - возвращает id обьекта
 isinstance(object , Type) -  является ли данный обьект данного типа
 issubclass(DeriveClass,BasClass) - унаследован ли данный класс от базового класса
 object.__doc__ - выводит документацию по обьекту
 callable(object) - проверяет , является ли обьект функцией
 
 
 

 class B:
   pass
 print isinstance(a, B)
 

 class Base:
   def out (self):
     print 'base'
 
 class Derived(Base):
   def out (self):
     Base.out(self)
 
 d = Derived()
 d.out()
 

 Нет , конструктор может быть только один :
 class C:
   def __init__(self, par1=None,par2=None,par3=None):
 В нем можно определить параметры , которые могут быть или не могут быть проинициализированы
 

 Есть 2 тестовых модуля :
     1 doctest
     2 unittest
 
 первый проверяет код на наличие комментариев в формате docstring.
 
 Пример unit-теста :
 
 import unittest, os
 from django.contrib.auth.models import User
 from django.core.files import File
 
 from my_app.models import *
 
 class TestMain(unittest.TestCase):
 
     def test_main(self):
 
         user_1 = User.objects.create_user(username='user1', password='123', email='user1@exmpl.com')
         self.assertEqual( user_1.id, 1)
 
 

 PyChecker , Pylint 
 

 Удаление :
   os.remove(filename) ,  os.unlink(filename)
 Копирование :
   shutil.copyfile()
 

 import struct
 
 f = open(filename, "rb") # бинарный режим на чтение
 s = f.read(8)
 x, y = struct.unpack(">hl", s)
 h - 2 байта , l - 4 байта , > - big endian
 x - 2-байтовое число
 y - 4-байтовое число
 

  Нужно использовать модуль popen2
 import popen2
 fromchild, tochild = popen2.popen2("command")
 tochild.write("input\n")
 tochild.flush()
 output = fromchild.readline()
 

 Нужно использовать модуль httplib :
 import httplib, sys, time
 qs = "First=Josephine&MI=Q&Last=Public"
 httpobj = httplib.HTTP('www.some-server.out-there', 80)
 httpobj.putrequest('POST', '/cgi-bin/some-cgi-script')
 httpobj.putheader('Accept', '*/*')
 httpobj.putheader('Connection', 'Keep-Alive')
 httpobj.putheader('Content-type', 'application/x-www-form-urlencoded')
 httpobj.putheader('Content-length', '%d' % len(qs))
 httpobj.endheaders()
 httpobj.send(qs)
 reply, msg, hdrs = httpobj.getreply()
 if reply != 200:sys.stdout.write(httpobj.getfile().read())
 

 Надо использовать модуль Cookie :
 
 Записать куку :
 
 import time, Cookie
 # создаем обьект SimpleCookie 
 cookie = Cookie.SimpleCookie()
 cookie['lastvisit'] = str(time.time())
 print cookie
 print 'Content-Type: text/html\n'
 print ''
 print 'Server time is', time.asctime(time.localtime())
 print ''
 
 Прочитать куку :
 
 cookie_string = os.environ.get('HTTP_COOKIE')
 cookie.load(cookie_string)
 
 
 

 Это конструкция , напоминающая си-шный макрос , 
 позволяющая определить функцию динамически в ран-тайме .
 Лямбда может использоваться прямо внутри кода и представляет одно-строчное выражение.
   Например :
   sq=lambda x: x**2 
   print sq(2) 
   4
 

  Ассерт позволяет проверить логическую истинность
    assert len(body) == body_len
 
 Если условие не выполняется, питон генерит исключение, которое прибьет код,
 если ассерт не будет обрамлен в блок try/catch.
  
 

  Перед строкой поставить u :
     u 'test' 
 

 f1=open("python_samples","r")
 print f1.readlines()
 

 a = 5
 b = 9
 def swap(c,d):
   return d,c
 a,b = swap(a,b)  
 print a , b
 

 s = 'aaa bbb ccc ddd eee'
 a = string.split(s)
 print a
 b=''
 for aa in a:
   b += str(aa)  
 print b
 

 Используя спецификатор * или *
 def  my_void(*args, **kwargs):
     args_0 = args[0]
     args_1 = args[1]
     args_2 = args[2]
     print '... args[0]='  +str(args_0)
     print '... args[1]='  +str(args_1)
     print '... args[2]='  +str(args_2)
     kwargs_0 = kwargs.pop('param_0')
     kwargs_1 = kwargs.pop('param_1')
     print '... kwargs[0]='  +str(kwargs_0)
     print '... kwargs[1]='  +str(kwargs_1)
     
 kwargs={}    
 args=(111,222,333)    
 kwargs['param_0']='123'
 kwargs['param_1']='456'
 my_void(*args,**kwargs)    
 

  Позволяет сохранить обьект на какой-то стадии его жизни , а потом извлечь его для дальнейшего использования
 Конвертация питоновского обьекта в строку называется pickling . 
 Обратный процесс - unpickling. Эта строка может быть сохранена на диске или в памяти . 
 Первая операция имеет вид :
   pickle.dump(x, f) 
 где x - обьект , f - файл.
 Вторая операция  :
   x = pickle.load(f)
 
 
 
 
 
 

 Модуль - это файл с расширением .py . Имя файла является именем модуля . 
 Для импорта этого модуля нужно :
   import module_name
 Для обращения к методам модуля :
   module_name.method()
 
 Модуль может содержать как методы , так и выполняемый код вне методов , который будет выполняться один раз ,
 при загрузке модуля .
  Для импорта части методов модуля :
   from module_name import method1 , method2
 
 Для загрузки модуля с аргументами в нем должна быть функция main :
 python module_name arg1 
 if __name__ == "__main__":
     import sys
     method3(int(sys.argv[1]))
 
 Функция dir() без аргументов выведет имена всех переменных и методов , определенных в текущем модуле .
 

 Пакет - это способ организации нескольких модулей , обьединенных одним корневым каталогом .
 Основной префикс использования - точка .
 Рассмотрим структуру вложенного каталога sound :
 
 sound/
   __init__.py
   formats
     __init__.py
     wavread.py
     wavwrite.py
     ...
   effects/                  
     __init__.py
     echo.py
     surround.py
 
 В каждом подкаталоге должен находиться файл __init__.py - это говорит питону о том,что каталог входит в пакет.
 Тогда использовать можно так :
   import sound.effects.echo
 

 В классе нужно определить 2 стандартных метода - __iter__ и next .
 Метод __iter__ будет возвращать обьект через метод next :
 
 class Reverse:
     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]
 
 for char in Reverse('12345'):
   print char
 5
 4
 3
 2
 1
 

 Генератор - функция , которая производит последовательность результатов вместо одного.
 def counter (maximum):
     i = 0
     while i < maximum:
         yield i
         i += 1
 
 x = counter(5)
 print x.next()
 print x.next()
 print x.next()
 print x.next()
 

 Дан массив : s=[1,2,3,4,5]
 Нулевой индекс - у первого элемента . Индекс -1 у последнего , -2 у предпоследнего , и т.д.
 

  самый быстрый вариант :
   list.reverse()
 

 list1 = [1,7,6,8]
 list2 = [4,3,99,22]
 pairs = list1 + list2
 pairs.sort()
 print pairs
 

 Те же списки , которые не могут быть изменены
   Списки определяются в квадратных скобках , tuple - в круглых
 

 Словарь хорош , когда быстро нужно получить значение по его ключу .
 Когда вам нужен индексированный доступ , используйте списки .
 

 num_strings = ['1','21','53','84','50','66','7','38','9']
 num = [] 
 n = len(num_strings) 
 for i in range(0,n):
   num.append(int(num_strings[i]))
   print num
 

 n = [1,2,5,10,3,100,9,24]
 r = []
 for e in n:
   if e>=10: 
       r.append(e)
 print r
 

 List=[1,5,4,6,7,2,1,2,3,5,7,6]
 print List
 List.sort()
 last = List[-1]
 for i in range(len(List)-2, -1, -1):
   if last==List[i]: del List[i]
   else: last=List[i]
 print List
 

 List=[[1,2],[3,4],[5,6]]
 print List[0][1]
 print List[2][0]
 

 
 a = [66.25, 333, 333, 1, 1234.5]
 
 Найти индекс элемента :
 a.index(1234.5)
 Добавить:
 a.insert(2, -1)
 a.append(333)
 a.extend([3,4,5]) - отличие extend от append  в том , что можно добавлять сразу несколько элементов в конец
 Удалить:
 a.remove(333) - удаление конкретного элемента
 a.pop() - удаление последнего элемента 
 Реверс , сортировка :
 a.reverse()
 a.sort()
 
 С помощью del можно удалить как отдельный элемент , так и весь список :
 >>> a = [-1, 1, 66.25, 333, 333, 1234.5]
 >>> del a[0]
 >>> a
 [1, 66.25, 333, 333, 1234.5]
 >>> del a[2:4]
 >>> a
 [1, 66.25, 1234.5]
 >>> del a[:]
 >>> a
 
 
 

 filter(function, sequence) - проверяет входящую последовательность и возвращает из нее те элементы , 
 для которых функция равна true , например : простые числа в диапазоне от 2 до 25 :
 
 def f(x): 
   return x % 2 != 0 and x % 3 != 0
 x = filter(f, range(2, 25))
 
 map(function, sequence) - для каждого элемента входящей последовательности вычисляется новое значение 
 и возвращается новая последовательность :
 
 def cube(x): 
   return x*x*x
 x = map(cube, range(1, 11))
 
 reduce(function, sequence) - берутся 2 элемента из входящей последовательности , вычисляется результат ,
 затем вычисляется для результата и следующего элемента , и т.д. :
 
 def add(x,y): 
   return x+y
 x = reduce(add, range(1, 4))
 
 
 

 Сеты - это коллекция уникальных неупорядоченных immutable элементов . 
 Это не списки, потому что не позволяют индексирования, и это не мапы, 
 ибо здесь нет пар ключ-значение.
 Используется для проверки уникальности .
 Имеет встроенные операции типа union, intersection, difference, symmetric difference. 
 
 basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
 print set(basket)  
 set(['orange', 'pear', 'apple', 'banana'])
 
 a = set('abracadabra')
 b = set('alacazam')
 
 print a                                  # unique letters in a
 set(['a', 'r', 'b', 'c', 'd'])
 
 print b                                  # unique letters in b
 print a - b                              # letters in a but not in b
 print a | b                              # letters in either a or b
 print a & b                              # letters in both a and b
 print a ^ b                              # letters in a or b but not both
 

 Функция может строит словарь , используя пары , хранимые в tuple : 
 print  dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
 print  dict([(x, x**2) for x in (range(2, 10))])     
 

 Использовать словарный метод iteritems() для словаря :
 knights = {'gallahad': 'the pure', 'robin': 'the brave'}
 for k, v in knights.iteritems():
   print k, v
 
 Использовать метод enumerate() для списков :
 x=['11','2222',3,4,5]
 for i, v in enumerate(x):
   print i, v
 
 Для одновременного прохода по двум спискам используется функция zip():
 questions = ['name', 'quest', 'favorite color']
 answers = ['lancelot', 'the holy grail', 'blue']
 for q, a in zip(questions, answers):
   print 'What is your %s?  It is %s.' % (q, a)
 
 
 Для прохода списка в обратной последовательности - функция reversed():
 for i in reversed(xrange(1,10,2)):
 ...     print i
 
 
 Для прохода списка в отсортированном порядке - функция sorted():
 basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
 for f in sorted(set(basket)):
   print f
 
 

 Используем генератор :
 import os
 import fnmatch
 def gen_find(filepat,top):
     for path, dirlist, filelist in os.walk(top):
         for name in fnmatch.filter(filelist,filepat):
             yield os.path.join(path,name)
 
 pyfiles = gen_find("*.py","./")
 for name in pyfiles:
   print name
 

 Функция будет выводить строки , добавляемые в конец файла .
 import time
 def follow(thefile):
     thefile.seek(0,2)      # Go to the end of the file
     while True:
          line = thefile.readline()
          if not line:
              time.sleep(0.1)    # Sleep briefly
              continue
          yield line
 
 logfile = open("access")
 loglines = follow(logfile)
 for line in loglines:
     print line,
 

 В качестве стека : последний вошел - первый вышел
 stack = [3, 4, 5]
 stack.append(6)
 stack.append(7)
 stack.pop()
 7
 stack
 [3, 4, 5, 6]
 
 В качестве очереди : первым вошел - первым вышел 
 from collections import deque
 queue = deque([1,2,3])
 queue.append(4)           
 queue.append(5)          
 queue.popleft()     
 queue
 [2,3,4,5]
 

 []
 

 Создается пустой класс:
 class Employee:
     pass
 
 Создаем обьект класса:
 john = Employee() 
 
 Присваиваем атрибуты:
 john.name = 'John Doe'
 john.dept = 'computer lab'
 john.salary = 1000
 
 

 Большие куски кода можно тестировать на производительность с помощью модулей profile и pstats. 
 Производительность кода можно тестировать с помощью модуля Timer :
 >>> from timeit import Timer
 >>> Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
 0.57535828626024577
 >>> Timer('a,b = b,a', 'a=1; b=2').timeit()
 0.54962537085770791
 
 Первый вариант с традиционным свопом , как показывает тест , идет медленнее , 
 нежели во втором варианте , в котором за кадром остается временное создание tuple . 
 
 

 Нужно использовать модуль threading , стартовать поток , а потом можно вызвать джойн ,
 чтобы дождаться его завершения .
 
 import threading, zipfile
 
 class AsyncZip(threading.Thread):
     def __init__(self, infile, outfile):
         threading.Thread.__init__(self)
         self.infile = infile
         self.outfile = outfile
     def run(self):
         f = zipfile.ZipFile(self.outfile, 'w', zipfile.ZIP_DEFLATED)
         f.write(self.infile)
         f.close()
         print 'Finished background zip of: ', self.infile
 
 background = AsyncZip('mydata.txt', 'myarchive.zip')
 background.start()
 background.join()    # ждем , пока поток финиширует
 
 
 

 Обьект array похож на список , но хранит данные более компактно.
 В следующем примере массив чисел хранится в 2-байтовом формате :
 from array import array
 a = array('H', [4000, 10, 700, 22222])
 
 
 

  Похож на список , с более быстрым добавлением и извлечением - позволяет извлекать
 элементы не только с конца, но и с начала :
 from collections import deque
 d = deque(["task1", "task2", "task3"])
 d.append("task4")
 d.popleft()
 (["task2", "task3", "task4"])  
 d.pop()
 (["task2", "task3"])  
 
 

  Он манипулирует списками в порядке сортировки .
 Например , вставить в нужную позицию элемент в отсортированный список :
 import bisect
 scores = [(100, 'perl'), (200, 'tcl'), (400, 'lua'), (500, 'python')]
 bisect.insort(scores, (300, 'ruby'))
 [(100, 'perl'), (200, 'tcl'), (300, 'ruby'), (400, 'lua'), (500, 'python')]
 
 Поиск:
 L=[4,6,2,7,3,9,6,8]
 L.sort()
 print bisect.bisect_left(L,7)
 print L
 
 Используется принцип бинарного поиска.
 
 
 

  Модуль re реализует поддержку регулярных выражений в питоне . 
 Главнейшая функция этого модуля : 
   re.search(pattern, string, flags=0)
 где pattern - регулярное выражение
 string - поисковая строка
 flags - флаги для использования модификаторов
 
 Пример : в поисковой строке out ищется шаблон типа даты часы:минуты:секунды: 20:12:06 - hh:mm:ss
   find_duration    = re.search('[0-9]{2}:[0-9]{2}:[0-9]{2}', out)
       if find_duration:
           duration = find_duration.group(0)
           hours    = int(duration[0:2])
           minutes  = int(duration[3:5])
           seconds  = int(duration[6:8])
 
 Для замены используется функция sub :
   sub(pattern, repl, string, max=0)
 pattern - поисковый шаблон
 repl    - строка , заменяющая найденный шаблон
 string  - исходня строка  
 
 Пример :   имеется номер телефона в виде
   phone = "2004-959-559"
 Нужно убрать тире :
   num = re.sub(r'\D', "", phone)  
 
 
 

 Методы keys() , values() , items() возвращают списки :
   ключей
   значений
   пар ключ-значение
 
 Метод has_key() ищет конкретный ключ
 
 Методы итерации - iterkeys() , itervalues() ,  iteritems() -
 выводят в цикле ключи , значения , пары ключ-значение
 
 d = {1:11,2:22,3:33,4:44,5:55}
 print d.keys()
 print d.values()
 print d.items()
 print d.has_key(1)
 
 for i in d.iterkeys():
  print i
 for i in d.itervalues():
  print i
 for i in d.iteritems(): 
  print i
 

 clear() - очищает словарь
 dict1.update(dict2) - обьединяет 2 словаря , при совпадении ключей , заменяет на dict2.value
 get() - возвращает значение по ключу либо None
 popitem() - удаляет последнюю пару ключ-значение
 pop()     - удаляет пару  по ключу
 setdefault(key,value) - аналогичен get , но добавляет пару , если ее нет в словаре
  
 
 a = {1:11,2:22,3:33,4:44,5:55}
 b = {6:66,7:77,8:88,9:99}
 a.update(b)
 print a
 print b
 print a.get(1)
 print a.get(11)
 a.popitem()
 print a
 a.pop(7)
 print a
 
 

 Словарь - это таблица ссылок на обьекты , где доступ к обьекту происходит по ключу.
 Это неотсортированная коллекция, реализованная как динамически расширяемая хеш-таблица.
 Термин mapping относится к словарям и указывает на то , что значение доступно по ключу
 и недоступно по индексу . 
 

 Атрибут класса становится private для этого класса , если он начинается с 2-х символов подчеркивания :
  
 class A:
   b=1
   _c=2
   __d=2
   
   def __init__(self):
     print 'A init'
     print self.__d
     
     
 class B(A):    
   a=11
   def __init__(self):
     print 'B init'
     #print self.__d    # error
   
 a = A()  
 print a.b
 print a._c
 b = B()  
 
 #print a.__d    # error
 
 Для модуля соответственно вместо двух символов подчеркивания используется один.
 
 

 __init__(self) - конструктор
 __del__(self)  - деструктор
 repr  - возвращает символьное представление класса
 str   - аналогично repr
 format - аналогично repr
 hash  - возвращает уникальный ключ для обьекта
 getattr(self,'name_var') - возвращает значение атрибута по имени
 setattr(self,'name_var',value) - устанавливает значение атрибута
 delattr(self,'name_var') - удаляет последнее присваивание для атрибута либо сам атрибут
 
 

 sys - переменные окружения и интерпретатора , командная строка , потоки  ввода-вывода
 string - константы и переменные для работы со строками
 os - интерфейс работы с операционной системой
 re - регулярные выражения
 socket, cgi, urllib, email, http - работа с интернетом
 math,time,datetime,thread,queue - другие стандартные модули
   
 

 find - находит подстроку в строке , возвращает индекс вхождения
   title = "Monty Python's Flying Circus"
   title.find('Python')
 
 join - обьединяет элементы списка в строку с помощью разделителя
   seq = ['1', '2', '3', '4', '5']
   sep = '.'
   a = sep.join(seq) 
   print a
   1.2.3.4.5
 
 lower() - возвращает строку в нижнем ключе
 
 replace(src,dst) - заменяет в строке подстроку src на подстроку dst
   my_str = my_str.replace(',',' ')
 
 string.split(str,',') - разбивает строку на список строк , в данном случае в качестве разделителя в строке ищется запятая
 string.split() без аргумента в качестве разделителя принимает пробел(-ы) .
 
 strip() - удаляет пробелы в начале и в конце строки
 
 translate(src,symbol) - аналогично replace , но заменяет единичный символ
 
 

 Присваивание списку переменных списка значений :
   x,y,z = 1,2,'333'
 
 

 Property - атрибут класса , возвращаемый через стандартную функцию , 
 которая в качестве аргументов принимает другие функции класса :
   
 class DateOffset:
     def __init__(self):
         self.start = 0
     
     def _get_offset(self):
         self.start +=  5
         return self.start 
 
     offset = property(_get_offset)
 
 
 d = DateOffset()
 print d.offset
 5
 print d.offset
 10
 

 Используются традиционные tcp-функции bind,listen,accept в питоновской обертке :
 
 Server:
 import socket
 s = socket.socket()
 host = socket.gethostname()
 port = 1234
 s.bind((host, port))
 s.listen(5)
 while True:
     c, addr = s.accept()
     print 'Got connection from', addr
     c.send('Thank you for connecting')
     c.close()
 
 Client:
 import socket
 s = socket.socket()
 host = socket.gethostname()
 port = 1234
 s.connect((host, port))
 print s.recv(1024)
 
 

  Нужно создать свой класс для создания протокола обмена данными .
 Обьект этого класса будет создан с помощью стандартного класса  Factory . 
 
 Server:
 from twisted.internet import reactor
 from twisted.internet.protocol import Protocol, Factory
 class MyServer(Protocol):
     def connectionMade(self):
         print 'Got connection from', self.transport.client
 
 factory = Factory()
 factory.protocol = MyServer
 reactor.listenTCP(1234, factory)
 reactor.run()
 
 
 
 Client:
 from twisted.internet import reactor, protocol
 from twisted.internet.protocol import ClientFactory, Protocol
  
 class MyClient(Protocol):
      def connectionMade(self):
          print "Connected to %s." % self.transport.getPeer( ).host
 
 client_factory = ClientFactory() 
 client_factory.protocol = MyClient
 reactor.connectTCP('127.0.0.1', 1234,client_factory)
 reactor.run( )
 
 

 Обработчик запросов Handler вызывает различные стандарные методы  в зависимости
 от клиента . Для чтения используется атрибут self.rfile , для записи - self.wfile . 
 
 
 from SocketServer import TCPServer, StreamRequestHandler
 class Handler(StreamRequestHandler):
     def handle(self):
         addr = self.request.getpeername()
         print 'Got connection from', addr
         self.wfile.write('Thank you for connecting')
 server = TCPServer(('', 1234), Handler)
 server.serve_forever()
 
 

 Использовать модуль urllib
 
 from urllib import urlopen
 import re
 text = urlopen('http://iakovlev.org/').read()
 print text
 
 

 1. Booleans : True или False.
 2. Numbers  : int (1,2...), long(123456789L) , floats (1.1,1.2...), decimal(0.1234567890 , ...) , fractions (1/2,2/3...), комплексные числа.
 3. Строки    : последовательность Unicode символов
 4. Байты 
 5. Списки    :  последовательность
 6. Tuples   :  immutable последовательность значений
 7. Set      :  уникальная последовательность
 8. Dictionaries : мапы (mappings) пар ключ-значение .
 
 
 

 Стандартный вывод :
   1. Запись в вывод :
   import sys
   for i in range(10):
     sys.stdout.write(str(i))
   2. Чтение вывода : 
     sys.stdout.read()
  
 
 

  Это обертка для функции или метода класса . 
 Представляет из себя декларацию непосредственно перед следующей за ней функцией,
 которая начинается с символа @.
 Пример: пусть у нас имеются несколько функций, возвращающих числа.
 Нужно в каждой функции поставить ассерт на случай, если функция возвращает отрицательное число,
 сгенерить исключение и вернуть ошибку . Можно было бы добавить в каждую функцию код, проверяющий результат
 и генерящий исключение. А если таких функций много ? В этом случае подойдет декоратор :
 
 def check_result(function):
   def wrapper(*args,**kargs):
     result = function(*args,**kargs)
     try:
       assert result >=0
       print result
     except:  
       print 'error'
       result='error'
     return result
   return wrapper
 
 
 @check_result
 def f1(x,y):
     return x-y
 
 @check_result
 def f2(x,y):
     return y-x
 
 f1(10,5)
 f2(10,5)
 
 >>> 5
 >>> error
 
 
 
 
 
 

 super - встроенная функция , которая позволяет доступ к атрибутам-методам базового класса
 class Mama(object): 
     def says(self):
         print 'mama says'
 
 class Sister(Mama):
   def says(self):
     Mama.says(self)
     print 'sister says'
 
 sister = Sister()
 sister.says()
 
 Вызов базового метода можно переписать 
 и тот же самый результат можно получить с помощью super : 
 class Sister(Mama):
   def says(self):
     super(Sister, self).says()
     print 'sister says'
 
 

 Данный паттерн позволяет создать всего один инстанс .
 Используется метод __new__ :
 
 class Singleton(object):
     a=1
     def __new__(cls, *args, **kw):
         if not hasattr(cls, '_instance'):
           orig = super(Singleton, cls)
           cls._instance = orig.__new__(cls, *args, **kw)
         return cls._instance
 
     
 one = Singleton()
 one.a = 3
 two = Singleton()
 three = Singleton()
 print two.a
 print three.a
 3
 3
 
 

 Это когда несколько переменных ссылаются на один обьект.
 
 Рассмотрим пример:
   a = 3
   b = a
 Две переменных указывают на один и тот же обьект.
   a = 4
 Создается второй обьект, на который указывает переменная a.
 При этом - переменная b по-прежнему указывает на 3.
 
 Другой пример:
   L1 = [1,2,3]  
   L2 = L1
 L1 и L2 указывают на один и тот же обьект.
   L1 = 24
 Будет создан второй обьект , L2 по прежнему будет указывать на список.
 
 Другой пример:
 >>> L = [1, 2, 3]
 >>> M = [1, 2, 3]
 >>> L == M
 True
 >>> L is M
 False
 Здесь - два разных обьекта с одинаковыми значениями.
 
 

  Для перегрузки пользовательского метода в классе в питоне используется двойное подчеркивание, 
 с которого начинается и заканчивается имя этого метода, 
 в этом случае будет вызван метод базового класса:
 
 class Base:
   def out(self):
     print 'Base'
     
 class Derived(Base):
   def __out__(self):
     print 'Derived'      
     
 d=Derived()
 d.out()
 
 >>> Base
 
 Полиморфизм в питоне основан на интерфейса , а не типах .
 Перегрузить методы можно за счет их списка аргументов:
 class C:
     def meth(self, x):
          ...
     def meth(self, x, y, z):
          ...
 
 
 

  Это базовый класс, который не может быть использован для создания обьектов.
 В нем должен быть хотя бы один абстрактный метод или свойство - т.е. нереализованный
 метод -  который реализуется в производном классе:
 
 class Base:
   def f1(self):
     self.f2()
     
 class Derived(Base):
   def f2(self):
     print 'Derived f2'      
     
 d=Derived()
 d.f1()
 
 В базовом классе нет метода f2() - он определен в Derived.
 
 
 

  Фабрика обьектов - это просто функция, генерящая обьекты для классов- 
 такая функция использует стандартный вызов apply и возвращает инстанс:
 
 def factory(aClass, *args, **kwargs):
     print aClass
     return apply(aClass, args, kwargs)
 
 class Spam:
     def doit(self, message):
         print message
 class Person:
     def __init__(self, name, job):
         self.name = name
         self.job = job
 
 object1 = factory(Spam)
 object2 = factory(Person, "Guido", "guru")
 
 
 
 
 

 Методы обьектов классов можно вызывать как с параметром self , так и без -
 в первом случае вызов будет называться unbound, во втором - bound:
 
 class Spam:
     def doit(self, message):
         print message
 
 Bound-вызов:
 object1 = Spam( )
 x = object1.doit
 x('hello world')
 
 UnBound-вызов:
 object1 = Spam( )
 t = Spam.doit
 t(object1, 'howdy')
 
 
 

 Классическая проблема с множественным наследованием- рассмотрим схему,
 когда от базового класса A порождены 2 класса B и C, от которых
 в свою очередь порожден класс D:
 
                 A
                 |
             ---------
             |       |
             B       C
             ---------
                 |
                 D
 
 class A:      attr = 1
 class B(A):   pass
 class C(A):   attr = 2
 class D(B,C): pass
 x = D( )
 print x.attr
 
 >>> 1
 
 Мы вправе были ожидать аттрибут=2, но он перекрывается классом A.
 Это классический вариант наследования.
 Вот новый стиль - new style - здесь класс C оказывается ниже класса A:
 
 class A(object): attr = 1
 class B(A):      pass
 class C(A):      attr = 2
 class D(B,C):    pass
 x = D( )
 print x.attr
 
 >>> 2
 
 
 
   
 
 
 

  Слоты - это список атрибутов, задаваемый в заголовке класса с помощью __slots__ .
 В инстансе необходимо назначить атрибут, прежде чем пользоваться им:
 
 class limiter(object):
     __slots__ = ['age', 'name', 'job']
     
 x=limiter()    
 x.age = 40
 print x.age
 
 
 
 
 
 

  Статический метод - функция, определенная вне класса и не имеющая атрибута self:
 
 class Spam:
     numInstances = 0
     def __init__(self):
         Spam.numInstances = Spam.numInstances + 1
     
 def printNumInstances( ):
     print "Number of instances created: ", Spam.numInstances
     
     
 a=Spam()
 b=Spam()
 
 printNumInstances()
 
 >>> Number of instances created: 2
 
 Статический метод может быть определен и внутри класса - для этого используется
 ключевое слово staticmethod - причем метод может быть вызван как статически,
 так и через инстанс:
 
 class Multi:
     def imeth(self, x):
         print self, x
     def smeth(x):
         print x
     def cmeth(cls, x):
         print cls, x
     smeth = staticmethod(smeth)
     cmeth = classmethod(cmeth)
     
 Multi.smeth(3)    
 
 >>> 3
 
 obj=Multi()
 obj.smeth(5)
 
 >>> 5
 
 Методы класса определяются с помощью ключевого слова classmethod - 
 здесь автоматически питон передает в качестве первого параметра сам класс - а не инстанс :
 
 Multi.cmeth(7)
 
 >>> 7
 
 obj.cmeth(10)
 
 >>> 10
 
 
 
 
 

  Конструкция with - это альтернатива для try/finally , появившаяся в питоне 2.6
 
     with object [as variable]:
         with-block
 
 object - это обьект
 Пример:
   with open(r'script') as myfile:
       for line in myfile:
           print line
 
 Если во время работы с файлом произойдет исключение, файл будет корректно закрыт.
 
 

  Находится первый минимум с помощью стандартной функции, удаляется, потом находится второй:
 
 L=[4,6,2,7,3,9,6,8]
 print L    
 smallest = min(L)
 min1 = L[smallest]
 print min1
 L.remove(smallest)
 next_smallest = min(L)
 min2 = L[next_smallest]
 print min2
 L.insert(min1, smallest)
 print L    
 
 
 

 Простейшее профилирование кода можно выполнить с помощью модуля time - 
 в примере измеряется время выполнения в секундах:
 
 import time
 
 L=[4,6,2,7,3,9,6,8,3,4,5,6,67,7,8,8,444,4,5,5,5,55555555,8,87,5,45,4,54,45,45,45]
 t1 = time.time()
 for i in range(1000000):
   L.sort()
   L.reverse()
   
 t2 = time.time()
 print "\t%.1f" % ((t2 - t1))
 
 
 

 
 def factorial(x):
     if x <= 1:
         return 1
     return x * factorial(x - 1)
 
 x = factorial(10)
 print x
 
 
 

  Это любой класс, имеющий спец. метод __call__ - при этом обьект можно вызвать как функцию :
 
 Пример - пусть у нас имеется класс Person, имеется коллекция обьектов этого класса - people,
 нужно отсортировать эту коллекцию по фамилиям. Для этого можно использовать функтор Sortkey
 
 
 class SortKey:
 
     def __init__(self, *attribute_names):
         self.attribute_names = attribute_names
 
     def __call__(self, instance):
         values = []
         for attribute_name in self.attribute_names:
             values.append(getattr(instance, attribute_name))
         return values
 
 class Person:
 
     def __init__(self, forename, surname, email):
         self.forename = forename
         self.surname = surname
         self.email = email
 
 people=[]
 p=Person('Petrov','','')
 people.append(p)
 p=Person('Sidorov','','')
 people.append(p)
 p=Person(u'Ivanov','','')
 people.append(p)
 for p in people:
   print p.forename
 
 people.sort(key=SortKey("forename"))  # вызов функтора SortKey
 
 for p in people:
   print p.forename
 
 >>> Ivanov
 >>> Petrov
 >>> Sidorov
 
 

  Дескриптор - это класс, который хранит и контролирует атрибуты других классов.
 Вообще любой класс, который имплементирует один из специальных методов -
 __get__ , __set__ , __delete__ , является дескриптором.
 Пример:
 
 class ExternalStorage:
 
     __slots__ = ("attribute_name",)
     __storage = {}
 
     def __init__(self, attribute_name):
         self.attribute_name = attribute_name
 
     def __set__(self, instance, value):
         self.__storage[id(instance), self.attribute_name] = value
 
     def __get__(self, instance, owner=None):
         if instance is None:
             return self
         return self.__storage[id(instance), self.attribute_name]
     
 class Point:
 
     __slots__ = ()
     x = ExternalStorage("x")
     y = ExternalStorage("y")
     def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
        
        
        
 p1=Point(1,2)       
 p2=Point(3,4)       
 print p1.x
 
 В данном случае класс Point не имеет собственных атрибутов x,y , хотя вызывает их как будто
 они есть - на самом деле они хранятся в дескрипторе ExternalStorage.
 
 
 

 
 В данном примере  2 скрипта - рarent.py и child.py.
 Запускается parent.py. 
 Child.py выступает в роли аргумента command, который передается в запускаемый процесс.
 У этого процесса есть стандартный вход, куда мы передаем 2 аргумента - поисковое слово и имя файла.
 Запись на стандартный вход осуществляет модуль subprocess.
 Каждый процесс пишет результат своего поиска в консоль.
 В главном процессе мы ждем, пока все child не закончат свою работу.
 
 Код parent.py:
 
 import os
 import subprocess
 import sys
 
 
 child = os.path.join(os.path.dirname(__file__), "./child.py")
 word  = 'word'
 file = ['./file1','./file2']
 
 pipes = []
 for i in range(0,2):
   command = [sys.executable, child]
   pipe = subprocess.Popen(command, stdin=subprocess.PIPE)
   pipes.append(pipe)
   pipe.stdin.write(word.encode("utf8") + b"\n")
   pipe.stdin.write(file[i].encode("utf8") + b"\n")
   pipe.stdin.close()
 
 while pipes:
     pipe = pipes.pop()
     pipe.wait()
 
 
 Код child.py:
 
 import sys
 
 word = sys.stdin.readline().rstrip()
 filename = sys.stdin.readline().rstrip()
 
 try:
     with open(filename, "rb") as fh:
         while True:
             current = fh.readline()
             if not current:
                 break
             if (word in current ):
                 print("find: {0} {1}".format(filename,word))
 except :
     pass
 
 
 
 Чтобы прочитать вывод процесса:
 
 ret = subprocess.call("ls -l", shell=True)
 p = subprocess.Popen("ls -l", shell=True, stdout=subprocess.PIPE)
 out = p.stdout.read()
 
 
 
 

 Нужно использовать пакет urllib:
 
 from urllib2 import urlopen          
 u = urlopen("ftp://username:password@somehostname/somefile")
 contents = u.read()