Фильтрование списков
Как вы уже знаете, Python позволяет преобразовывать списки с помощью расширенной записи. Такой подход можно комбинировать с фильтрованием, когда некоторые элементы отображаются, в то время как другие пропускаются.
Пример 2.13. Синтаксис фильтрования списков
[mapping-expression for element in source-list if filter-expression]
Это дополнительная возможность в , которую вы обязательно полюбите. Начало расширенной записи остается прежним, а в конце, начиная с if, добавляется условие, по которому будет производиться фильтрование. Условие может быть любым выражением, которое дает истину или ложь (в Python это может быть ). Любой элемент, для которого условие дает истину, будет участвовать в отображении. Все остальные элементы игнорируются, то есть в выражение отображения не подставляются и в результат не включаются.
Пример 2.14. Введение в фильтрование списков
>>> li = ["a", "mpilgrim", "foo", "b", "c", "b", "d", "d"] >>> [elem for elem in li if len(elem) > 1]
['mpilgrim', 'foo'] >>> [elem for elem in li if elem != "b"]
['a', 'mpilgrim', 'foo', 'c', 'd', 'd'] >>> [elem for elem in li if li.count(elem) == 1]
['a', 'mpilgrim', 'foo', 'c']
В данном случае выражение отображения совсем простое (значение каждого элемента), так что сосредоточьтесь на условии фильтра. Каждый элемент пробегаемого списка Python пропускает через фильтр. Если условие фильтра дает истину, элемент участвует в преобразовании и результат включается в возвращаемый список. В данном случае мы исключили все строки длиной в один символ. | |
Здесь мы исключаем элементы с одним определенным значением, "b". Обратите внимание, что фильтром отбрасываются все элементы со значением "b", так как во всех случаях выражение условия будет давать ложь. | |
Метод count списка возвращает количество вхождений элементов определенного значения в список. Вы можете подумать, что этот фильтр исключает все дубликаты, и возвращаемый список будет содержать по одному значению исходного списка. Но это не так, потому что значения, входящие в исходный список дважды (в данном случае это, "b" and "d") полностью исключаются. Существует множество способов исключить дубликаты из списка, но не так. |
Пример 2.15. Фильтрование списка в apihelper.py
methodList = [method for method in dir(object) if callable(getattr(object, method))]
Этот пример выглядит сложным, но основная структура остается прежней. Все выражение дает список, который присваивается переменной methodList. Выражение отображения простое: оно дает значение каждого элемента. Функция dir(object) возвращает список всех атрибутов и методов объекта object — это тот список, который мы преобразуем. И единственная новая часть — это условие фильтра после if.
Выражение фильтра выглядит жутко, но он таковым не является. Вы уже знаете о , и . Как вы могли видеть в , выражение getattr(object, method) дает объект-функцию, если object является модулем и method содержит имя функции из этого модуля.
Таким образом, мы берем объект object, получаем список имен его атрибутов, методов, функций, и затем фильтруем этот список, избавляясь от всего, что нас не интересует. Для того, чтобы избавиться от ненужного, мы берем имя каждого атрибута/метода/функции, с помощью функции getattr получаем настоящий объект. Затем мы проверяем, поддерживает ли объект вызов, таким образом подхватывая все функции и методы — как встроенные (например, метод pop списков), так и определенные пользователем (например, функция buildConnectionString в модуле odbchelper). Нас не интересуют другие атрибуты, такие как обязательный для всех моделей атрибут __name__.
Дополнительная литература
описывает другой способ фильтрования списков .
5 | ||
Copyright © 2000, 2001, 2002 Copyright © 2001, 2002, 2003 Перевод, |
Сила самоанализа
Содержание
2.1. 2.2. 2.3. 2.4. 2.5. 2.6. 2.7. 2.8. 2.9.
Использование lambda-функций
Python поддерживает интересный синтаксис, позволяющий определять небольшие однострочные функции на лету. Позаимствованные из Lisp, так назыаемые lambda-функции могут быть использованы везде, где требуется функция.
Пример 2.21. lambda-функции
>>> def f(x): ... return x*2 ...
>>> f(3) 6 >>> g = lambda x: x*2
>>> g(3) 6 >>> (lambda x: x*2)(3)
6
Эта lambda-функция делает то же самое, что и обычная функция, определенная выше. Обратите внимание на сокращенный синтаксис: список аргументов записывается без скобок и ключевое слово return
отсутствует (оно подразумевается, так как тело функции может содержать только одно выражение). Кроме того, функция не имеет имени, но может быть вызвана через переменную, которой она присвоена. | |
Вы можете использовать lambda-функцию даже не присваивая ее переменной. Это не самый полезный пример, но он показывает, что lambda-функция может быть определена прямо в месте ее использования. |
Обобщая, lambda-функция — это функция, которая имеет произвольное число аргументов (включая ) и возвращает значение одного выражения. lambda-функции не могут содержать инструкций или более одного выражения. Не пытайтесь втискивать в lambda-функцию слишком много. Если вам необходимл что-либо более сложное — определите обычную функцию.
Использование lambda-функций — дело стиля. Везде, где вы можете использовать lambda-функцию, вы также можете определить и использовать обычную функцию. Я их использую в местах, где нужно инкапсулировать характерный код, не подлежащий повторному использованию, без замусоривания программы множеством маленьких однострочных функций. |
Пример 2.22. lambda-функции в apihelper.py
processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
Здесь следует обратить внимание на несколько вещей. Во-первых, мы используем простую форму приема с . В данном случае это оправданно, так как lambda-функция всегда является истиной (но это не означает, что lambda-функция не может возвращать значение, являющееся ложью; функция всегда является истиной, не зависимо от возвращаемого значения).
Во-вторых, мы используем метод split без аргументов. Вы уже видели его использование , без аргументов метод split разбивает строку по символам пропуска (пробел, табуляция, возврат коретки, переход на новую строку).
Пример 2.23. split без аргументов
>>> s = "this is\na\ttest"
>>> print s this is a test >>> print s.split()
['this', 'is', 'a', 'test'] >>> print " ".join(s.split())
'this is a test'
Это строка, которая содержит символ переход на новую строку, записанный в виде специальной последовательности (такие строки могут быть также записаны с использованием ). \n — переход на новую строку, \t — символ горизонтальной табуляции. | |
Метод split без аргументов разбивает строку по символам пропуска. В данном случае три пробела, переход на новую строку и табуляция воспринимаются одинаково. | |
Вы можете нормализовать пропуски разбив строку, а затем снова объединив ее, используя один пробул в качестве разделителя. Именно это делает функция help для того, чтобы свернуть строку документации. |
Пример 2.24. Присваивание функции переменной
processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s)
processFunc теперь ссылается на функцию, но на какую — это зависит от значения переменной collapse. Если collapse является истиной, processFunc(string)
будет сворачивать символы пропуска, в противном случае processFunc(string)
будет возвращать аргумент без изменений.
Для того, чтобы сделать это на менее мощном языке, например на Visual Basic, вы, скорее всего, будете использовать интсрукцию if, чтобы решить, сворачивать символы пропуска или нет. Такой подход неэффективен, так как проверять условие придется при каждом вызове функции. В языке Python вы можете принять решение один раз и определить lambda-функцию, которая будет делать только то, что вам нужно.
Дополнительная литература
описывает использование lambda
для . показывает, как ( поясняет, что в будущих версиях Python это будет сделать проще).В приводятся примеры .
7 | ||
Copyright © 2000, 2001, 2002 Copyright © 2001, 2002, 2003 Перевод, |
Необязательные и именованные аргументы
В языке Python аргументы функции могут иметь значения по умолчанию, оно будет использовано, если при вызове функции значение этого аргумента не указано. Более того, аргументы имеющие значение по умолчанию при вызове могут быть указаны в произвольном порядке, если указано имя аргумента. В хранимых процедурах для SQL сервера Transact/SQL также могут быть использованы именованные аргументы; если вы пишите сценарии для SQL сервера, можете лишь бегло ознакомиться с этим разделом.
Пример 2.4. help — функция с двумя необязательными аргументами
def help(object, spacing=10, collapse=1):
Аргументы spacing и collapse могут быть опущены при вызове, так как для них определены значения по умолчанию. Аргумент object не имеет значения по умолчанию, поэтому должен быть указан всегда. Если функция help вызывается только с одним аргументом, то spacing принимает значение 10 и collapse принимает значение 1. Если help вызывается с двумя аргументами, collapse также принимает значение 1.
Представьте теперь, что вы хотите указать значение аргумента collapse, но использовать значение по умолчанию для spacing. В большинстве языков вам придется передавать все три аргумента. Однако Python позволяет передавать аргументы в произвольном порядке по имени.
Пример 2.5. Возможные способы вызова help
help(odbchelper)
help(odbchelper, 12)
help(odbchelper, collapse=0)
help(spacing=15, object=odbchelper)
С одним аргументом, spacing и collapse получают значения по умолчанию, 10 и 1 соответственно. | |
С двумя аргументами, collapse получает значение по умолчанию 1. | |
Здесь вы явно указываете имя аргумента, collapse, для которого передается значение. Аргумент spacing
по-прежнему получает значение по умолчанию 10. | |
Даже обязательные аргументы (в данном случае — object), которые не имеют значения по умолчанию, могут быть переданы по имени, и именованные аргументы могут быть указаны в произвольном порядке. |
Это выглядит странным, пока вы не увидите, что список значений аргументов фактически является словарем.
“Обычный” же способ передачи аргументов без указания их имен является сокращенной записью: интерпретатор сопоставляет значения аргументов их именам в соответствии с порядком, в котором они были указаны в определении функции. В большинстве случаев вы вызываете функции “обычным” способов, но при необходимости всегда можете воспользоваться дополнительной возможностью.
Все что Вам нужно сделать для вызова функции — это указать значение для каждого обязательного аргумента. Способ передачи аргументов и порядок их следования — дело Вашего вкуса. |
описывает, . Это важно в случаях, когда значение по умолчанию является списком, словарем или другим изменяемым объектом.
2 | ||
Copyright © 2000, 2001, 2002 Copyright © 2001, 2002, 2003 Перевод, |
Объединяем все вместе
Последняя строка кода и единственная еще не разобранная — делает всю работу. Но теперь задача совсем проста, так как все, что нам необходимо, уже готово. Все костяшки домино на месте, осталось только толкнуть их.
Пример 2.25. Основная часть apihelper.py
print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList])
Обратите внимание, что это одна команда разбитая на несколько строк без явного использования признака продолжения (“\”). Помните, я говорил, что без использования обратного слэша? Расширенная запись списков — один из таких случаев, так как все выражение заключено в квадратные скобки.
Давайте разберем его с конца. Фраза
for method in methodList
говорит о том, ято мы имеем дело с . Как вы уже знаете, methodList является списком объекта object. Таким образом мы пробегаем по списку методов и каждый метод доступен через переменную method.
Пример 2.26. Динамическое извлечение строки документации
>>> import odbchelper >>> object = odbchelper
>>> method = 'buildConnectionString'
>>> getattr(object, method)
<function buildConnectionString at 010D6D74> >>> print getattr(object, method).__doc__
Создает и возвращает строку соединения из словаря параметров.
В функцию help object — объект, для которого мы хотим получить помощь — передается в качестве аргумента. | |
По ходу того, как мы пробегаем по списку methodList, method содержит имя текущего метода. | |
С помощью функции мы получаем сам метод method объекта object. | |
Теперь осталось самое простое — распечатать строку документации метода. |
Следующий кирпичик — использование функции str. Как вы уже знаете, str — встроенная функция, . Но строка документации уже является строкой, так зачем же суетиться с использованием функции str? На самом деле не каждая функция имеет строку документации, и если строки документации нет, ее атрибут __doc__ равен None.
Пример 2.27. Зачем использовать str для строк документации?
>>> {}.keys.__doc__
>>> {}.keys.__doc__ == None
1 >>> str({}.keys.__doc__)
'None'
Метод keys словаря не имеет строки документации, так что его атрибут __doc__ равен None. Если вы набираете выражение для атрибута __doc__ непосредственно в интерактивном режиме, интерпретатор Python ничего не выводит, что может сбить с толку (такое поведение интерпретатора действительно удобно, если впомнить о процедурах, которые в языке Python возвращают None). | |
Вы можете убедиться, что атрибут __doc__ действительно равен None простым сравнением. | |
Функция str возвращает строковое представление объекта, в данном случае 'None'. |
В SQL вы должны использовать IS NULL вместо = NULL для сравнения с пустым значением. В языке Python вы можете использовать как == None, так и is None, но второй вариант работает быстрее. |
для None будет сгенерировано исключение, так как у None нет метода split.
Далее мы снова используем форматирование, чтобы соединить значение, возвращаемое функцией processFunc, со результатом применения метода ljust к строке method. Это новый метод строковых объектов, который мы раньше не видели.
Пример 2.28. Метод ljust
>>> s = 'buildConnectionString' >>> s.ljust(30)
'buildConnectionString ' >>> s.ljust(20)
'buildConnectionString'
ljust дополняет строку пробелами до указанной длины. Именно это делает функция help при выводе в две колонки для выравнивания строк документации во второй колонке. | |
Если требуемая длина меньше, чем исходная длина строки, ljust вернет строку без изменений. Этот метод никогда не обрезает строку. |
Имея метод ljust, дополняющий имя метода пробелами до нужной длины, и строку документации (возможно со свернутыми символами пропуска), которую возвращает processFunc, мы объединяем их и получаем одну строку. Так как мы пробегаем по списку methodList, то получим список строк. Используя метод join
строки "\n", мы объединяем строки в одну с символом перехода на новую строку в качестве разделителя и печатаем результат.
Пример 2.29. Печать списка
>>> li = ['a', 'b', 'c'] >>> print "\n".join(li)
a b c
Этот прием также будет будет полезен при отладке для вывода списков. А в языке Python вы будете работать со списками постоянно. |
Пример 2.30. Основная часть apihelper.py, пересмотренная
print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList])
8 | ||
Copyright © 2000, 2001, 2002 Copyright © 2001, 2002, 2003 Перевод, |
Особенности операторов and и or
В языке Python операторы and и or, как вы и ожидали, выполняют булевы операции, но они не возвращают булевы значения: результатом всегда является значение одного из операндов.
Пример 2.16. Оператор and
>>> 'a' and 'b'
'b' >>> '' and 'b'
'' >>> 'a' and 'b' and 'c'
'c'
При использовании оператора and, значения вычисляются в булевом контексте слева напрво. Значения 0, '', [], (), {} и None
являются ложью, все остальное является истиной[3]. Если у and оба операнда являются истиной, результатом будет последнее значение. В данном случае вычисляется выражение 'a', которое является истиной, затем 'b', которое также является истиной, и возвращается 'b'. | |
Если какой-либо из операндов является ложью, результатом будет первое такое значение. В данном случает '' — первое значение, являющееся ложью. | |
Все значения являются истиной, так что в результате мы получаем последнее — 'c'. |
Пример 2.17. Оператор or
>>> 'a' or 'b'
'a' >>> '' or 'b'
'b' >>> '' or [] or {}
{} >>> def sidefx(): ... print "in sidefx()" ... return 1 >>> 'a' or sidefx()
'a'
Как и для and опреранды or вычисляются в булевском контексте слева направо. Если операнд является истиной, or
немедленно возвращает результат. В данном случае 'a' — первое истинное значение. | |
or вычисляет выражение '', которое является ложью, затем 'b', которое является истиной, и возвращает 'b'. | |
Если все значения являются ложью, or возвращает последнее. or вычисляет '' (ложь), []
(ложь), затем {} (ложь) и возвращает {}. | |
Обратите внимание, что or вычисляет операнды до тех пор, пока не найдет истинное значение, остальное игнорируется. Это имеет значение, когда вычисление операнда дает сторонние эффекты. В данном случае функция sidefx не вызывается, так как для получения результата выражения с опереатором or достаточно того, что первый операнд, 'a', является истиной. |
Если вы используете C, то, наверное, знакомы с выражением bool ? a : b, которое дает a, если bool
является истиной, b, если bool
ложно. Благодаря особенностям работы операторов and и or
в Python, вы можете достигнуть анологичного эффекта.
Пример 2.18. Прием с and-or
>>> a = "first" >>> b = "second" >>> 1 and a or b
'first' >>> 0 and a or b
'second'
Синтаксис bool ? a : b в языке Python выглядит похоже. Все выражение вычисляется слева направо, так что оператор and применяется первым. 1 and 'first' дает 'first', затем 'first' or 'second' дает 'first'. | |
0 and 'first' дает 0, тогда 0 or 'second' дает 'second'. |
Пример 2.19. Когда прием с and-or не работает
>>> a = "" >>> b = "second" >>> 1 and a or b
'second'
Так как a — пустая строка, которую Python считает ложью в булевом контексте, 1 and '' дает '', а '' or 'second' дает 'second'. Ой! Это не то, что мы хотели получить. |
Прием с and-or, bool and a or b, не будет работать так же, как конструкция bool ? a : b в C, если a является ложью. |
Пример 2.20. Безопасное использование приема с and-or
>>> a = "" >>> b = "second" >>> (1 and [a] or [b])[0]
''
Так как выражение [a] является непустым списком, оно никогда не будет ложно. Даже если a равно 0, '' или другому значению, являющемуся ложью, список [a] всегда будет являться истиной, потому что содержит один элемент. |
Кажется, этот прием не стоит того, чтобы его использовать. В конце концов вы всегда можете воспользоваться интсрукцией if. Тогда зачем вся эта суета? Конечно, в большинстве случаев выбирая между двумя константами вы можете использовать простой синтаксис и не беспокоиться, потому что значение a всегда будет истинным. И даже если придется использовать более сложный синтакс, на это могут найтись весские причины: в некоторых случаях в языке Python использование инструкции if не допускается, например в lambda-функциях.
Дополнительная литература
В обсуждаются .
Footnotes
[3] Ну, почти все. По умолчанию экземпляры классов являются истиной, но вы можете определить специальные методы в классе, чтобы его экземпляры могли быть ложью. Вы узнаете все о классах и специальных методах в главе 3.
6 | ||
Copyright © 2000, 2001, 2002 Copyright © 2001, 2002, 2003 Перевод, |
Получение атрибутов с помощью getattr
Вы уже знаете, что . Но вы пока не знаете, что если имя функции становится известно только во время выполнения программы, то ее можно получить с помощью функции getattr.
Пример 2.11. Функция getattr
>>> li = ["Larry", "Curly"] >>> li.pop
<built-in method pop of list object at 010DF884> >>> getattr(li, "pop")
<built-in method pop of list object at 010DF884> >>> getattr(li, "append")("Moe")
>>> li ["Larry", "Curly", "Moe"] >>> getattr({}, "clear")
<built-in method clear of dictionary object at 00F113D4> >>> getattr((), "pop")
Traceback (innermost last): File "<interactive input>", line 1, in ? AttributeError: 'tuple' object has no attribute 'pop'
Таким образом вы получаете метод pop списка. Обратите внимание, что вы не вызываете его (для этого нужно выполнить li.pop()), а получаете в виде объекта. | |
Здесь мы также получаем метод pop, но теперь имя метода указано в виде строкового аргумента функции getattr. getattr — очень полезная функция, позволяющая получить любой атрибут любого объекта. В данном случае объектом является список, а его атрибутом — метод pop. | |
В случае, если вы еще не до конца осознали, насколько это может быть полезным, попробуйте выполнить этот код: значение, возвращаемое функцией getattr является методом, который можно вызвать, как если бы вы просто вызвали li.append("Moe"). Но вы не вызываете метод напрямую — вы указываете имя метода в виде строки. | |
getattr работает и для словарей. | |
Теоретически, getattr работает и для кортежей, но , так что getattr сгенерирует исключение независимо от имени атрибута, которое вы дадите. |
getattr предназначен не только для встроенных типов данных. Он также работает и для модулей.
Пример 2.12. getattr в apihelper.py
>>> import odbchelper >>> odbchelper.buildConnectionString
<function buildConnectionString at 00D18DD4> >>> getattr(odbchelper, "buildConnectionString")
<function buildConnectionString at 00D18DD4> >>> object = odbchelper >>> method = "buildConnectionString" >>> getattr(object, method)
<function buildConnectionString at 00D18DD4> >>> type(getattr(object, method))
<type 'function'> >>> import types >>> type(getattr(object, method)) == types.FunctionType 1 >>> callable(getattr(object, method))
1
Так мы можем получить функцию buildConnectionString из модуля odbchelper, который сы изучали в разделе . (Шестнадцатиричный адрес характерен для моей машины, у вас он будет другим.) | |
Используя getattr, мы можем получить ту же самую функцию. В общем, getattr(object, "attribute") дает такой же результат, как object.attribute. Если object является модулем, attribute может быть любым объектом, определенном в этом модуле: функцией, классом или другой глобальной переменной. | |
На самом деле именно это и делает функция help. object передается функции в качестве аргумента; method является строкой с именем метода или функции. | |
В данном случае, method содержит имя функции, в чем мы можем убедиться получив ее . | |
Так как method является функцией, ее можно . |
4 | ||
Copyright © 2000, 2001, 2002 Copyright © 2001, 2002, 2003 Перевод, |
В глубь
Эта глава описывает одну из самых сильных возможностей языка Python — самоанализ. Ка вы уже знаете, . Самоанализ — использование специального кода для просмотра в памяти модулей и функций как объектов, извлекая информацию о них и о том, как их использовать. По ходу мы будем определять функции без имени, передавать аргументы в неправильном порядке и использовать функции, имена которых до этого даже не знали.
Ниже приведена законченная работающая программа на языке Python. Вы должны понять большую часть кода просто просмотрев ее. Пронумерованные строки используют концепции, описанные в главе . Не беспокойтесь, если оставшаяся часть кода выглядит пугающе, в этой главе вы узнаете все, что необходимо для его понимания.
Пример 2.1. apihelper.py
Если вы еще этого не сделали, можете , используемые в книге.
def help(object, spacing=10, collapse=1):
"""Выводит методы и строки документации.
В качестве аргумента может использоваться модуль, класс, список, словарь или строка.""" methodList = [method for method in dir(object) if callable(getattr(object, method))] processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList])
if __name__ == "__main__":
print help.__doc__
Этот модуль определяет одну функцию — help. Она воспринимает три аргумента: object, spacing и collapse. Последние два аргумента, как мы скоро увидим, не являются обязательными. | |
Функция help имеет многострочную , кратко описывающую предназначение функции. Обратите внимание, что здесь не упомянуто возвращаемое значение — функция предназначениа для выполнения определенных действий а не возврата значения. | |
Тело функции . | |
с if __name__ позволяет использовать модуль в качестве программы без каких-либо конфликтов. В данном случае программа просто выводит строку документации функции help. | |
для сравнения используется оператор ==. Заключать в скобки выражение совсем не обязательно. |
Функция help предназначена для использования программистом при работе в Python IDE. В качестве аргумента можно использовать любой объект, имеющий функции (например, модуль) или методы (например, список). Эта функция выводит имена функций (или метододов) объекта и их строки документации.
Пример 2.2. Использование apihelper.py
>>> from apihelper import help >>> li = [] >>> help(li) append L.append(object) -- append object to end count L.count(value) -> integer -- return number of occurrences of value extend L.extend(list) -- extend list by appending list elements index L.index(value) -> integer -- return index of first occurrence of value insert L.insert(index, object) -- insert object before index pop L.pop([index]) -> item -- remove and return item at index (default last) remove L.remove(value) -- remove first occurrence of value reverse L.reverse() -- reverse *IN PLACE* sort L.sort([cmpfunc]) -- sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1
По умолчанию информация выводится в легко воспринимаемом виде. Многострочные строки документации преобразуются в одну длинную строку, но это особенность можно отключить, передав 0 в качестве аргумента collapse. Кроме того, если имена функций содержат 10 символов, вы можете установить большее значение аргумента spacing.
Пример 2.3. Дополнительные возможности apihelper.py
>>> import odbchelper >>> help(odbchelper) buildConnectionString Build a connection string from a dictionary Returns string. >>> help(odbchelper, 30) buildConnectionString Build a connection string from a dictionary Returns string. >>> help(odbchelper, 30, 0) buildConnectionString Build a connection string from a dictionary
Returns string.
1 | ||
Copyright © 2000, 2001, 2002 Copyright © 2001, 2002, 2003 Перевод, |
В качестве аргумента может использоваться
Теперь код программы apihelper.py обрел смысл.
Пример 2.31. apihelper.py
def help(object, spacing=10, collapse=1): """Выводит методы и строки документации.
В качестве аргумента может использоваться модуль, класс, список, словарь или строка.""" methodList = [method for method in dir(object) if callable(getattr(object, method))] processFunc = collapse and (lambda s: " ".join(s.split())) or (lambda s: s) print "\n".join(["%s %s" % (method.ljust(spacing), processFunc(str(getattr(object, method).__doc__))) for method in methodList])
if __name__ == "__main__": print help.__doc__
Пример 2.32. Вывод apihelper.py
>>> from apihelper import help >>> li = [] >>> help(li) append L.append(object) -- append object to end count L.count(value) -> integer -- return number of occurrences of value extend L.extend(list) -- extend list by appending list elements index L.index(value) -> integer -- return index of first occurrence of value insert L.insert(index, object) -- insert object before index pop L.pop([index]) -> item -- remove and return item at index (default last) remove L.remove(value) -- remove first occurrence of value reverse L.reverse() -- reverse *IN PLACE* sort L.sort([cmpfunc]) -- sort *IN PLACE*; if given, cmpfunc(x, y) -> -1, 0, 1
Перед тем как перейти к следующей главе убедитесь, что вы овладели следующими навыками:
Определение и вызов функций с Использование функции для получения строкового представления произвольного объектаИспользование функции для динамического доступа к атрибутамИспользование расширенной записи списков для Распозновани и его безопасное использованиеОпределение и использование этой переменной для вызова. Понимание этого приема жизнено необходимо для понимания языка Python. В книге вы увидите более сложные приложения этой концепции.
A.0. PreambleThe purpose of this License is to make a manual, textbook, or other written document "free" in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of "copyleft", which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
A. GNU Free Documentation LicenseСодержание A.0. A.1. A.2. A.3. A.4. A.5. A.6. A.7. A.8. A.9. A.10. A.11. Version 1.1, March 2000 Copyright (C) 2000 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Документирование функцийВ языке Python вы можете документировать функции, снабжая их строками документации. Пример 1.4. Определение строки документации для buildConnectionString def buildConnectionString(params): """Создает и возвращает строку соединения из словаря параметров.""" Утроенные кавычки используются для многострочных строковых литералов. Все, что находится между утроенными кавычками, является одним строковым значением, включая символы перехода на новую строку и другие символы кавычек. Вы можете использовать их где угодно, но чаще всего их употребляют для определения строк документации.
Первая строка в определении функции (то есть первая после двоеточия) является строкой документации, в которой поясняется, что функция делает. Python не требует наличия строки документации у функции, но все же ее стоит всегда определять. Я знаю, вы слышали об этом на каждой лекции по программированию, но Python дает вам дополнительный стимул: строка документации доступна во время выполнения программы в качестве атрибута функции.
Дополнительная литература В обсуждается, как написать хорошую строку документации. описывает общепринятую .
Форматированное представлениеPython позволяет получить форматированное представление значений в виде строки. Хотя строка формата может содержать довольно сложные выражения, чаще всего используется вставка значений в строку с помощью шаблона %s.
Пример 1.28. Введение в форматирование >>> k = "uid" >>> v = "sa" >>> "%s=%s" % (k, v) 'uid=sa'
Обратите внимание, что (k, v) является кортежем. Я уже говорил, что кортежи весьма полезный тип данных. Вы можете подумать, что здесь слишком много работы для простого объединения строк. И вы будете правы, но форматирование — это не просто объединение строк. Это даже не просто форматирование. Данная операция также выполняет приведение типа. Пример 1.29. Форматирование vs. объединение >>> uid = "sa" >>> pwd = "secret" >>> print pwd + " is not a good password for " + uid secret is not a good password for sa >>> print "%s is not a good password for %s" % (pwd, uid) secret is not a good password for sa >>> userCount = 6 >>> print "Users connected: %d" % (userCount, ) Users connected: 6 >>> print "Users connected: " + userCount Traceback (innermost last): File "<interactive input>", line 1, in ? TypeError: cannot add type "int" to string
Дополнительная литература В описаны . описывает , а также технику их использования, включая .
Знакомство с языком PythonСодержание 1.1. 1.2. 1.3. 1.4. 1.5. 1.6. 1.7. 1.8. 1.9. 1.10. 1.11. 1.12. 1.13. 1.14. 1.15. КортежиКортеж — это неизменяемый список. С момента создания кортеж не может быть изменен никакими способами. Пример 1.22. Определение кортежей >>> t = ("a", "b", "mpilgrim", "z", "example") >>> t ('a', 'b', 'mpilgrim', 'z', 'example') >>> t[0] 'a' >>> t[-1] 'example' >>> t[1:3] ('b', 'mpilgrim')
Пример 1.23. У кортежей нет методов >>> t ('a', 'b', 'mpilgrim', 'z', 'example') >>> t.append("new") Traceback (innermost last): File "<interactive input>", line 1, in ? AttributeError: 'tuple' object has no attribute 'append' >>> t.remove("z") Traceback (innermost last): File "<interactive input>", line 1, in ? AttributeError: 'tuple' object has no attribute 'remove' >>> t.index("example") Traceback (innermost last): File "<interactive input>", line 1, in ? AttributeError: 'tuple' object has no attribute 'index' >>> "z" in t 1
Так для чего же нужны кортежи? Работа с кортежами быстрее, чем со списками. Если вы определяете постоянный набор значений, и все, что вы хотите с ним когда-либо делать, это перебирать его элементы, используйте кортеж вместо списка.Помните, я сказал, что в качестве могут выступать числа, строки и объекты “некоторых других типов”? Кортежи могут быть ключами словаря, а списки нет.[2]Как мы скоро увидим, кортежи используются для получения форматированного представления.
Дополнительная литература обучает работе с кортежами и показывает как . показывает как . объясняет как . Footnotes [2] На самом деле все несколько сложнее. Ключи словаря должны быть неизменяемыми. Кортежи сами по себе неизменяемы, но, если у вас имеется кортеж списков, то он считается изменяемым и не может быть использован в качесве ключа словаря. Только кортежи чисел, строк и других таких же кортежей могут быть ключами словаря.
Объединение и разбиение строкВы имеете список строк с парами ключ-значение вида key=value и хотите объединить их в одну строку. Для этих целей можно воспользоваться методом join строковых объектов. Пример 1.34. Объединение строк в buildConnectionString return ";".join(["%s=%s" % (k, v) for k, v in params.items()]) Перед тем, как мы продолжем, сделаю одно интересное замечание. Я постоянно повторяю, что функции являются объектами, строки являются объектами, все является объектами. Вы могли подумать, что под строковыми объектами подразумевались строковые переменные. Но нет, посмотрите внимательно на этот пример, и вы увидете, что строка ";" сама по себе является объектом, метод join которого вы вызываете. В любом случае, метод join объединяет элементы списка в одну строку, в которой элементы оказываются разделены точкой с запятой. Совсем не обязательно, чтобы в качестве разделителя выступала точка с запятой, не обязательно, чтобы он был одним символом — разделитель может быть произвольной строкой.
Пример 1.35. Вывод программы odbchelper.py >>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"} >>> ["%s=%s" % (k, v) for k, v in params.items()] ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret'] >>> ";".join(["%s=%s" % (k, v) for k, v in params.items()]) server=mpilgrim;uid=sa;database=master;pwd=secret Именно эту строку возвращает функция buildConnectionString и выводит программа. Историческая справка. Когда я начал изучать Python, я ожидал, что join будет методом списка, а строка-разделитель — его аргументом. Многие люди думали точно также. До появления версии Python 1.6 строки не имели всех этих полезных методов.
['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret'] >>> s.split(";", 1) ['server=mpilgrim', 'uid=sa;database=master;pwd=secret']
отвечает на и содержит множество . описывает . содержит информацию о . объяняет, , а не списков.
Объявление функцийВ языке Python, как и в большинстве других языков программирования, есть функции, но в нем нет отдельных заголовочных файлов, как в C++, или разделов интерфейс/реализация, как в языке Pascal. Если вам нужна функция — просто определите ее. Пример 1.3. Определение функции buildConnectionString def buildConnectionString(params): Здесь необходимо сделать несколько замечаний. Во-первых, определение функции начинается с ключевого слова def, после которого следуют имя функции и, в скобках, аргументы. В данном примере функция имеет только один аргумент, если же функция должна воспринимать несколько аргументов, они перечисляются через запятую. Во-вторых, вы не определяете тип возвращаемого значения. В языке Python никогда не указывается не только тип возвращаемого значения, но даже его наличие. На самом деле каждая функция возвращает значение; если функция выполняет инструкцию return, она возвращает указанное в ней значени, иначе функция возвращает специальное значение — None.
В третьих, не указан тип аргумента params. В языке Python тип переменных никогда не указывается явно. Python отслеживает тип объектов во время выполнения программы.
Дополнение. Эрудированный читатель прислал мне следуещее объяснение сравнения Python с другими языками программирования: Язык со статической типизациейЯзык, в котором тип (переменной, возвращаемого значения) должен быть указан, например Java или C.Язык с динамической типизациейЯзык, в котором тип определяется во время выполнения.
Обработка списковОдна из самых мощных особенностей языка Python — расширенная запись списков, которая позволяет легко преобразовать один список в другой, применяя к каждому элементу функцию. Пример 1.30. Введение в расширенную запись списков >>> li = [1, 9, 8, 4] >>> [elem*2 for elem in li] [2, 18, 16, 8] >>> li [1, 9, 8, 4] >>> li = [elem*2 for elem in li] >>> li [2, 18, 16, 8]
Пример 1.31. Расширенная запись списка в buildConnectionString ["%s=%s" % (k, v) for k, v in params.items()] Во-первых, обратите внимание на вызов метода items словаря params. Этот метод возвращает список кортежей, которые представляют записи в словаре. Пример 1.32. keys, values, and items >>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"} >>> params.keys() ['server', 'uid', 'database', 'pwd'] >>> params.values() ['mpilgrim', 'sa', 'master', 'secret'] >>> params.items() [('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')]
Давайте теперь посмотрим, что делает функция buildConnectionString. Она берет список params.items() и преобразует его, применяя к каждому элементу строку формата. Полученный список будет содержать такое же количество элементов, как и params.items(), но каждый элемент будет являться строкой с ключом и ассоциированным с ним значением из словаря params. Пример 1.33. Расширенная запись списка в buildConnectionString, шаг за шагом >>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"} >>> params.items() [('server', 'mpilgrim'), ('uid', 'sa'), ('database', 'master'), ('pwd', 'secret')] >>> [k for k, v in params.items()] ['server', 'uid', 'database', 'pwd'] >>> [v for k, v in params.items()] ['mpilgrim', 'sa', 'master', 'secret'] >>> ["%s=%s" % (k, v) for k, v in params.items()] ['server=mpilgrim', 'uid=sa', 'database=master', 'pwd=secret']
описывает другой способ преобразования элементов списка — . описывает, как использовать .
Определение переменныхПосле того, как вы познакомились со словарями, кортежами и списками, давайте вернемся к нашему примеру программы — odbchelper.py. В языке Python есть локальные и глобальные переменные, как и в большинстве других языков, но нет их явного объявления. Переменные появляются, когда им присваивают значение, и автоматически уничтожаются при выходе из области видимости. Пример 1.24. Определение переменной myParams if __name__ == "__main__": myParams = {"server":"mpilgrim", \ "database":"master", \ "uid":"sa", \ "pwd":"secret"} Здесь есть несколько интересных моментов. Во-первых, обратите внимание на отступы. Инструкция if является составной и ее тело должно вводиться с отступом, как и тело функции. Во-вторых, одна инструкция присваивания переменной записана в несколько строк с использованием обратного слэша (“\”) в качестве признака наличия продолжения.
В третьих, вы нигде не объявляли переменную myParams, а просто присвоили ей значение. Это соответствует поведению VBScript без опции option explicit. К счастью, в отличии от VBScript, Python не позволит ссылаться на переменную, которой нигде не было присвоено значение — при попытке это сделать будет сгенерировано исключение. Пример 1.25. Использование несуществующей переменной >>> x Traceback (innermost last): File "<interactive input>", line 1, in ? NameError: There is no variable named 'x' >>> x = 1 >>> x 1 В один прекраснй день вы будете благодарны языку Python за такое поведение. Дополнительная литература приводит примеры, и .
ОтступыВ определении функций нет явных begin и end, нет фигурных скобок, обозначающих начало и конец тела функции. Единственным разделителем является двоеточие (“:”) плюс отсуп кода в теле функции. Пример 1.6. Отступы в определении функции buildConnectionString def buildConnectionString(params): """Создает и возвращает строку соединения из словаря параметров.""" return ";".join(["%s=%s" % (k, v) for k, v in params.items()]) Блоки кода (функции, инструкций if, for и др.) определяются отступами. Увеличение отступа обозначает начало блока и уменьшение — его конец. Никакие дополнительные скобки или ключевые слова для этих целей не используются. Таким образом отступы являются значимыми и должны быть согласованными. В приведенном примере тело функции (включая строку документации) набрано с отступом в четыре пробела. Число пробелов в отступе не обязательно должно быть равно четырем, но должно быть везде одинаковым. Первая строка, без отступа, находится за пределами тела функции. После некоторого протеста вы смиритесь с ролью отступов в языке Python и увидите преимущества такого подхода. Программы на языке Python выглядят схожими, так как отступы являются требованием языка, а не стилем. Поэтому чужой код воспринимается гораздо легче.
Дополнительная литература В обсуждаются вопросы, связанные с переносимостью различных вариантов отступов, и показаны . описывает общепринятый стиль использования отступов.
Присваивание сразу нескольких значенийОдна из приятных возможностей языка Python — использование последовательностей для односременного присваивания нескольких значений. Пример 1.26. Присваивание сразу нескольких значений >>> v = ('a', 'b', 'e') >>> (x, y, z) = v >>> x 'a' >>> y 'b' >>> z 'e'
Использовать эту возможность можно по-разному. У меня часто возникает необходимость присвоить переменным диапазон значений. В языке C, вы бы использовали тип enum и вручную перечислили каждую константу и ассоциированное с ней значение, что утомительно, особенно, если значения идут подряд. Python позволяет использовать встроенную функцию range совместно с множественным присваиванием. Пример 1.27. Присваивание идущих подряд значений >>> range(7) [0, 1, 2, 3, 4, 5, 6] >>> (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7) >>> MONDAY 0 >>> TUESDAY 1 >>> SUNDAY 6
Множественное присваивание также полезно при использовании функций, возвращающих несколько значений в виде кортежа. Вы просто присваиваете их отдельным переменным. Так поступают многие стандартные библиотеки языка Python, включая модуль os, который обсуждается в главе 3. Дополнительная литература В показано, как использовать множественное присваивание для .
СловариСделаем небольшое отступление, так как вам необходимо познакомиться со словарями, кортежами и списками. Если вы знаток Perl, то уже имеете некоторое представление о словарях и списках, но вам, тем не менее, необходимо обратить внимание на кортежи. Один из втроенных типов языка Python, словарь, сопоставляет ключам значения.
Пример 1.9. Определени словарей >>> d = {"server":"mpilgrim", "database":"master"} >>> d {'server': 'mpilgrim', 'database': 'master'} >>> d["server"] 'mpilgrim' >>> d["database"] 'master' >>> d["mpilgrim"] Traceback (innermost last): File "<interactive input>", line 1, in ? KeyError: mpilgrim
Пример 1.10. Изменение словарей >>> d {'server': 'mpilgrim', 'database': 'master'} >>> d["database"] = "pubs" >>> d {'server': 'mpilgrim', 'database': 'pubs'} >>> d["uid"] = "sa" >>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'pubs'}
>>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'pubs'} >>> d["retrycount"] = 3 >>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'master', 'retrycount': 3} >>> d[42] = "douglas" >>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'master', 42: 'douglas', 'retrycount': 3}
Пример 1.12. Удаление записей из словарей >>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'master', 42: 'douglas', 'retrycount': 3} >>> del d[42] >>> d {'server': 'mpilgrim', 'uid': 'sa', 'database': 'master', 'retrycount': 3} >>> d.clear() >>> d {}
>>> d = {} >>> d["key"] = "value" >>> d["key"] = "other value" >>> d {'key': 'other value'} >>> d["Key"] = "third value" >>> d {'Key': 'third value', 'key': 'other value'}
обучает работе со словарями и показывает, как . приводит множество .В обсуждается .В описаны .
СпискиСписок являются одним из самых используемых типов данных в языке Python. Если все ваше знакомство со списками ограничивается массивами в Visual Basic или (не дай бог) datastore в Powerbuilder, возмите себя в руки для знакомства со списками в языке Python.
Пример 1.14. Определение списков >>> li = ["a", "b", "mpilgrim", "z", "example"] >>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li[0] 'a' >>> li[4] 'example'
Пример 1.15. Отрицательные индексы >>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li[-1] 'example' >>> li[-3] 'mpilgrim'
Пример 1.16.
['b', 'mpilgrim'] >>> li[1:-1] ['b', 'mpilgrim', 'z'] >>> li[0:3] ['a', 'b', 'mpilgrim']
>>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li[:3] ['a', 'b', 'mpilgrim'] >>> li[3:] ['z', 'example'] >>> li[:] ['a', 'b', 'mpilgrim', 'z', 'example']
>>> li ['a', 'b', 'mpilgrim', 'z', 'example'] >>> li.append("new") >>> li ['a', 'b', 'mpilgrim', 'z', 'example', 'new'] >>> li.insert(2, "new") >>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new'] >>> li.extend(["two", "elements"]) >>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements'] >>> li.index("example") 5 >>> li.index("new") 2 >>> li.index("c") Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: list.index(x): x not in list >>> "c" in li 0
Пример 1.20. Удаление элементов из списка >>> li ['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements'] >>> li.remove("z") >>> li ['a', 'b', 'new', 'mpilgrim', 'example', 'new', 'two', 'elements'] >>> li.remove("new") >>> li ['a', 'b', 'mpilgrim', 'example', 'new', 'two', 'elements'] >>> li.remove("c") Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: list.remove(x): x not in list >>> li.pop() 'elements' >>> li ['a', 'b', 'mpilgrim', 'example', 'new', 'two']
>>> li = ['a', 'b', 'mpilgrim'] >>> li = li + ['example', 'new'] >>> li ['a', 'b', 'mpilgrim', 'example', 'new'] >>> li += ['two'] >>> li ['a', 'b', 'mpilgrim', 'example', 'new', 'two'] >>> li = [1, 2] * 3 >>> li [1, 2, 1, 2, 1, 2]
обучает работе со списками и делает важные замечания по поводу . показывает, как . отвечает на и содержит множество . описывает .
Тестирование модулейМодули в языке Python также являются объектами и имеют несколько полезных атрибутов. Вы можете использовать их, например, для тестирования. Пример 1.7. Прием с if __name__ if __name__ == "__main__": Несколько замечаний, перед тем как мы перейдем к главному. Во-первых, выражение в инструкции if совсем не обязательно заключать в скобки. Во-вторых, заголовок инструкции закачивается двоеточием, после которого следует .
Так что же делает этот прием с if? Модули являются объектами и имеют атрибут __name__. Значение этого атрибута зависит от того, как используется модуль. Если вы импортируете модуль, атрибут __name__ равен имени файла без каталога и расширения. Но если вы запускаете модуль как отдельную программу, __name__ будет иметь специальное значение — __main__. Пример 1.8. __name__ импортированного модуля >>> import odbchelper >>> odbchelper.__name__ 'odbchelper' Зная об этом, вы можете определить код для тестирования модуля непосредственно в самом модуле. При непосредственном запуске модуля __name__ будет равен __main__, что приведет к выполнению теста. При импортировании же модуля __name__ будет иметь другое значение, и тест будет проигнорирован. Такой подход облегчает разработку и отладку новых модулей перед включением их в большую программу.
Дополнительная литература подробно описывает, что происходит при .
В глубьЗдесь представлена полноценная программа на языке Python. Возможно эта программа не представляет для вас никакого смысла. Не беспокойтесь, мы проанализируем каждую строку. Но сначала прочитайте ее и посмотрите, в чем вы смогли разобраться самостоятельно. Пример 1.1. odbchelper.py Если вы еще этого не сделали, можете , используемые в книге. def buildConnectionString(params): """Создает и возвращает строку соединения из словаря параметров.""" return ";".join(["%s=%s" % (k, v) for k, v in params.items()]) if __name__ == "__main__": myParams = {"server":"mpilgrim", \ "database":"master", \ "uid":"sa", \ "pwd":"secret"} print buildConnectionString(myParams) Теперь запутите программу и посмотрите, что произойдет.
Пример 1.2. Вывод odbchelper.py server=mpilgrim;uid=sa;database=master;pwd=secret
Все является объектамиЕсли вы не обратили внимание, я только что заметил, что функции в языке Python имеют атрибуты, и эти атрибуты доступны во время выполнения программы. Функция, как и все остальное в языке Python, является объектом. Пример 1.5. Доступ к строке документации функции buildConnectionString >>> import odbchelper >>> params = {"server":"mpilgrim", "database":"master", "uid":"sa", "pwd":"secret"} >>> print odbchelper.buildConnectionString(params) server=mpilgrim;uid=sa;database=master;pwd=secret >>> print odbchelper.buildConnectionString.__doc__ Создает и возвращает строку соединения из словаря параметров.
В языке Python все является объектами, и почти все из них имеют атрибуты и методы.[1] Все функции имеют специальный атрибут, который содержит строку документации, определенную в исходном коде. Это настолько важно, что я повторю еще раз: в языке Python все является объектами. Строки являются объектами.
и возвращает строку соединения изТеперь программа odbchelper.py и ее вывод приобретают смысл. Пример 1.37. odbchelper.py def buildConnectionString(params): """Создает и возвращает строку соединения из словаря параметров.""" return ";".join(["%s=%s" % (k, v) for k, v in params.items()]) if __name__ == "__main__": myParams = {"server":"mpilgrim", \ "database":"master", \ "uid":"sa", \ "pwd":"secret"} print buildConnectionString(myParams) Пример 1.38. Вывод программы odbchelper.py server=mpilgrim;uid=sa;database=master;pwd=secret Перед тем, как погрузиться в чтение второй главы, убедитесь, что вы овладели следующими навыками: Использование Python IDE в интерактивном режиме для проверки выраженийНаписание модуля Python таким образом, чтобы он мог быть запущен , хотябы с целью тестирования и вызов его функций, использование и , Определение , и Доступ к атрибутам и методам , включая строки, списки, словари, функции и модулиПолучение с помощью расширенной записи списков строк на подстроки и их объединение
|