Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 Tests
  Test Red Hat
  Test
  Test Perl
  Test King
  Test OS
  Test 486
  Test ANSI C
  Test LPG
  Test Kernel
=>  Test Python
NEWS
Последние статьи :
  Тренажёр 16.01   
  Эльбрус 05.12   
  Алгоритмы 12.04   
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
 
TOP 20
 Linux Kernel 2.6...3421 
 MINIX...3088 
 Solaris...2963 
 LD...2961 
 William Gropp...2284 
 Trees...2154 
 Rodriguez 6...2073 
 C++ Templates 3...1985 
 Kamran Husain...1940 
 Secure Programming for Li...1857 
 Максвелл 5...1766 
 DevFS...1754 
 Part 3...1742 
 Go Web ...1719 
 Ethreal 4...1671 
 Стивенс 9...1668 
 Stein-MacEachern-> Час...1663 
 Arrays...1642 
 Максвелл 1...1638 
 ffmpeg->tutorial...1588 
 
  01.01.2024 : 3621733 посещений 

 

 

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()