Журнал LinuxFormat - перейти на главную

LXF77:Python

Материал из Linuxformat
(Различия между версиями)
Перейти к: навигация, поиск
(Новая: ''Часть 3. Итак, познакомившись с типами данных, доступных в языке Python, мы, под чутким руководством '''Сер...)
 
м (Модули)
 
(не показаны 6 промежуточных версий 3 участников)
Строка 1: Строка 1:
 +
{{цикл/Python}}
 
''Часть 3. Итак, познакомившись с типами данных, доступных в языке Python, мы, под чутким руководством '''Сергея Супрунова''' морально готовы приступить к более серьёзным вещам. На сегодня программа-минимум – разобраться с модулями и научиться писать свои функции.''
 
''Часть 3. Итак, познакомившись с типами данных, доступных в языке Python, мы, под чутким руководством '''Сергея Супрунова''' морально готовы приступить к более серьёзным вещам. На сегодня программа-минимум – разобраться с модулями и научиться писать свои функции.''
  
Строка 7: Строка 8:
 
Для чего же нужны модули? Чуть позже, когда мы напишем свою функцию, вы увидите, что с помощью модуля очень легко реализуется концепция повторного использования кода. Пока же модули интересны нам как способ расширения возможностей вашей программы. С их помощью вы подключаете уже написанные кем-то наборы функций и методов, которые сможете использовать почти так же, как если бы они были встроенными (такими, как рассмотренная нами ранее '''float()''').
 
Для чего же нужны модули? Чуть позже, когда мы напишем свою функцию, вы увидите, что с помощью модуля очень легко реализуется концепция повторного использования кода. Пока же модули интересны нам как способ расширения возможностей вашей программы. С их помощью вы подключаете уже написанные кем-то наборы функций и методов, которые сможете использовать почти так же, как если бы они были встроенными (такими, как рассмотренная нами ранее '''float()''').
  
Начнем с модуля '''sys'''. В нем определен ряд переменных, содержащих информацию об операционной системе, дескрипторы стандартных потоков ввода, вывода и ошибок ('''stdin''', '''stdout''' и '''stderr''' соответствен но), и так далее. рассмотрим небольшой пример:
+
Начнем с модуля '''sys'''. В нем определен ряд переменных, содержащих информацию об операционной системе, дескрипторы стандартных потоков ввода, вывода и ошибок ('''stdin''', '''stdout''' и '''stderr''' соответственно), и так далее. рассмотрим небольшой пример:
  
 
<source lang="python">
 
<source lang="python">
Строка 30: Строка 31:
 
Теперь можно обращаться к объектам модуля непосредственно, но будьте осторожны – вы потеряете все определённые вами переменные и функции, имена которых совпадут с именами определенных в модуле.
 
Теперь можно обращаться к объектам модуля непосредственно, но будьте осторожны – вы потеряете все определённые вами переменные и функции, имена которых совпадут с именами определенных в модуле.
  
Символ «звездочка» в операторе '''from - import''' означает, что должно быть импортировано всё, что определено в модуле. Вы также можете перечислить только то, что желаете сделать доступным в вашей про грамме (например, '''from sys import version''').
+
{{Врезка|right|
 +
|Заголовок=ПОЛЕЗНЫЙ СОВЕТ
 +
|Содержание=
 +
Когда вы работаете в интерактивном терминале, к вашим услугам всегда функция help(). Используйте её, когда вам понадобится подсказка по той или иной функции или модулю. Не забывайте заключать в кавычки её аргумент – ведь вы передаёте имя функции, а не ее саму:
 +
'''help('dir'), help('sys')'''.
 +
|Ширина=250px}}
 +
 
 +
Символ «звездочка» в операторе '''from - import''' означает, что должно быть импортировано всё, что определено в модуле. Вы также можете перечислить только то, что желаете сделать доступным в вашей программе (например, '''from sys import version''').
  
 
Ещё одна важнейшая переменная модуля sys – список '''sys.argv''', в который в момент запуска Python-программы помещаются аргументы, переданные в командной строке. Пример использования этого списка вы увидите далее в данной статье.
 
Ещё одна важнейшая переменная модуля sys – список '''sys.argv''', в который в момент запуска Python-программы помещаются аргументы, переданные в командной строке. Пример использования этого списка вы увидите далее в данной статье.
  
 
==Модуль os==
 
==Модуль os==
 +
 +
Пожалуй, самый популярный модуль Python – это '''os'''. Он предоставляет  вам ряд функций, позволяющих взаимодействовать с операционной системой: '''chroot()''', '''mkdir()''', '''setuid()''' и так далее. Названия, думаю,  говорят сами за себя. а как посмотреть полный список функций, доступных в модуле, я надеюсь, вы ещё помните с прошлого урока: '''dir(os)'''.
 +
 +
Для работы с файловой системой практически незаменим подмодуль этого модуля – '''os.path'''. С его помощью вы можете определять типы файлов, установленные для них права доступа, и тому подобное. Нам ещё доведётся поработать с ним на практике.
 +
 +
==Прочие модули==
 +
 +
Вообще, в стандартную поставку Python входит несколько десятков  наиболее полезных модулей. Найти их можно в каталоге '''/usr/lib/python''' (на некоторых системах путь может быть иным, например, '''/usr/local/lib/python'''). Если быть точнее, то Python ищет свои модули в  каталогах, список которых возвращает переменная '''sys.path'''.
 +
 +
Обращайте внимание на файлы с расширением '''py''' ('''pyc''' и '''pyo''' – это байт-код модулей, который используется для экономии ресурсов, поскольку при обращении к модулю повторная компиляция не требуется). Названия большинства из них говорят сами за себя, к тому же вы можете открыть любой модуль, чтобы ознакомиться с его кодом и, как правило, очень подробными комментариями. С некоторыми из них мы обязательно столкнёмся в дальнейшем.
 +
 +
==Функции==
 +
 +
Со встроенными функциями вы уже знакомы. Но что делать, если возможностей, заложенных в интерпретатор или стандартные модули, вам недостаточно? Всё просто – напишите собственную функцию!
 +
 +
Пользовательская функция определяется оператором '''def''' (от '''define''' – определять). В качестве параметра указывается имя функции (оно  должно быть уникально в пределах пространства имён основной программы), а в скобках перечисляются её формальные аргументы. Далее  ставится двоеточие (как и в случае любых блочных операторов, таких как '''if''' или '''for'''), и на последующих строках, имеющих отступ, вводится код функции. Впрочем, когда речь идёт о Python, несколько строк кода способны сказать больше, чем пол-страницы текста на естественном языке. Чтобы лучше во всем разобраться, рассмотрим один пример (файл назовем '''abbr.py'''):
 +
 +
<source lang="python">
 +
#!/usr/bin/python
 +
# -*- coding: utf-8 -*-
 +
"""
 +
Программа обслуживает небольшой словарь сокращений, используя anydbm
 +
"""
 +
import sys, anydbm as db
 +
dictfile = 'dict.dbm'
 +
def openDictionary(dbmfile=dictfile):
 +
    """ Открыть словарь """
 +
    global dictionary
 +
    try:
 +
        dictionary = db.open(dbmfile, 'c')
 +
    except:
 +
        raise 'Ошибка открытия файла'
 +
def getMeaning(abbr):
 +
    """ Поиск расшифровки """
 +
    try:
 +
 +
        return dictionary[abbr]
 +
    except:
 +
        return '[не определено]'
 +
def addMeaning(abbr, meaning):
 +
    """ Добавить сокращение """
 +
    dictionary[abbr] = meaning
 +
    def delMeaning(abbr):
 +
    """ Удалить сокращение """
 +
    try:
 +
        del dictionary[abbr]
 +
    except:
 +
        pass
 +
if __name__ == "__main__":
 +
    openDictionary()
 +
    try:
 +
        command = sys.argv[1]
 +
        if command == '-a':
 +
            addMeaning(sys.argv[2], sys.argv[3])
 +
        elif command == '-d':
 +
            delMeaning(sys.argv[2])
 +
        else:
 +
            abbr = sys.argv[1]
 +
            print abbr + ' = ' + getMeaning(abbr)
 +
    except:
 +
        print """\
 +
Неверные аргументы. Допустимый синтаксис:
 +
abbr.py <ABBR>                  - расшифровать сокращение
 +
abbr.py -a <ABBR> <MEANING>    - добавить расшифровку
 +
abbr.py -d <ABBR>                - удалить сокращение
 +
"""
 +
else:
 +
    openDictionary()
 +
</source>
 +
 +
Эта программа реализует простейший консольный словарь сокращений. Только не забудьте сделать файл исполняемым ('''chmod u+x abbr.py'''). Поддерживаются три операции (информацию об этом вы получите, если попытаетесь вызвать сценарий с неправильными аргументами):
 +
#'''abbr.py <ABBR>''' – возвращает из словаря расшифровку сокращения <ABBR>;
 +
#'''abbr.py -a <ABBR>'' <MEANING>''' – добавляет в словарь расшифровку сокращения. В силу особенностей словарного типа данных в Python, эта же команда изменяет расшифровку для уже существующей аббревиатуры;
 +
#'''abbr.py -d <ABBR>''' – удаляет из словаря запись для указанного сокращения.
 +
 +
Обратите внимание на вторую строку – здесь указывается кодировка исходного текста (подробности см. на странице http://www.python.org/peps/pep-0263.html). Если вы используете не UTF-8, то укажите в этой строке свою кодировку (например, koi8-r).
 +
 +
Строки, обрамлённые утроенными кавычками, в данном случае можно рассматривать как многострочные комментарии.
 +
 +
Оператор '''global''' в функции '''openDictionary()''' делает переменную '''dictionary''' доступной за пределами функции. В противном случае её действие распространялось бы только на эту функцию. Ещё один интересный момент – то, как описан формальный аргумент функции. В данном случае мы задаем для переменной значение по умолчанию. Если в дальнейшем при вызове функции вы не передадите в неё аргумент, будет использовано значение переменной '''dictfile'''.
 +
 +
Несколько слов нужно сказать о самом модуле '''anydbm'''. С его помощью Python выполняет поиск доступного dbm-пакета в текущей системе (вам не нужно об этом беспокоиться). Данные в файле '''DBM''' организованы по словарному принципу (ключ – значение), поэтому данный файл может быть естественным образом сопоставлен с переменной типа «словарь». Все дальнейшие операции с данными словаря для программиста выглядят как обычные, а dbm-модуль позаботится о том, чтобы все данные оказались сохранены в файл. Собственно говоря, '''dbm'''-файл вы можете рассматривать как словарь, содержимое которого  не теряется между запусками программы. также обратите внимание, что  при подключении этого модуля мы используем псевдоним.
 +
 +
Итак, в функции '''openDictionary()''' мы открываем файл '''dict.dbm''' (второй параметр – ''''c'''' – даёт указание создать такой файл, если его ещё нет) и сопоставляем его со словарём '''dictionary'''. Конструкция «'''try – except'''» служит для обработки ошибок. В блок '''try''' мы помещаем потенциально опасные операции (которые могут завершиться с ошибкой), а блок '''except''' содержит код, который будет выполнен в случае возникновения ошибки в блоке '''try'''. Оператор raise генерирует сообщение об ошибке и прерывает выполнение программы.
 +
 +
Далее описаны три функции, реализующие заявленную выше функциональность. Пожалуй, в пояснении нуждается здесь только оператор pass в функции '''delMeaning()''': это пустой оператор, который ничего не делает – если нужного ключа в словаре нет, то и удалять нечего.
 +
 +
Ну и в конце сценария, в секции оператора '''if''', вы можете увидеть пример обработки аргументов командной строки.
 +
 +
Конечно, этот учебный пример не лишён недостатков: невозможно сделать несколько записей, имеющих одинаковую аббревиатуру, работа чувствительна к регистру символов (введя запись для «UDP», вы не сможете получить значение по ключу «udp»), и т.д. Однако сейчас нам важен не функционал, а собственно языковые конструкции.
 +
 +
==Возвращаясь к модулям==
 +
 +
Итак, мы написали функцию, которая может оказаться крайне полезной  в других программах. Как бы было хорошо, если бы оказалось возможным поместить её в модуль! А ведь нет ничего проще – она уже в модуле. Да-да! Вы можете просто подключить написанную выше программу в качестве модуля (одним из операторов, '''import''' или '''from''' – '''import''') и спокойно использовать определённые в ней переменные и функции!
 +
 +
В этом заключается одно из преимуществ Python по сравнению с его «прямым конкурентом» - языком Perl. В Perl вам пришлось бы специально оформлять вашу программу как модуль (как минимум, потребуется оператор '''package'''). В Python концепция повторного использования кода заложена в основу синтаксиса и не требует от вас совершенно никаких усилий.
 +
 +
Рассмотрим пример:
 +
 +
<source lang="python">
 +
#!/usr/bin/python
 +
# -*- coding: utf-8 -*-
 +
 +
import abbr
 +
abbr.delMeaning('UDP')
 +
print abbr.getMeaning('IP')
 +
</source>
 +
 +
Как видите, вам достаточно импортировать '''py'''-программу (расширение не указывается), и вы можете в полной мере воспользоваться всем созданным ранее. Единственное, этот файл должен быть доступен для поиска (самый простой вариант – поместить его в текущий  каталог).
 +
 +
Обратите внимание, что в момент импортирования переменная '''__name__''' в подключаемом модуле будет иметь значение, совпадающее с именем модуля. Поэтому в данном случае вместо секции '''if''' сценария '''abbr.py''' будет выполнена секция '''else'''. Подобный оператор '''if – else''' присутствует практически в каждой программе на языке Python и позволяет использовать ее и как модуль, и как самостоятельный сценарий (в последнем случае, как нетрудно догадаться, переменная '''__name__''' будет иметь значение '''"__main__"''').
 +
 +
Итак, вы уже в состоянии разрабатывать довольно серьёзные и полезные программы. Однако не научившись работать с классами, вы не познаете всю мощь Python. В следующий раз мы заполним и этот пробел.

Текущая версия на 18:33, 11 сентября 2010

Часть 3. Итак, познакомившись с типами данных, доступных в языке Python, мы, под чутким руководством Сергея Супрунова морально готовы приступить к более серьёзным вещам. На сегодня программа-минимум – разобраться с модулями и научиться писать свои функции.

Содержание

[править] Модули

Начнем со стандартных модулей. Стандартными их называют потому, что они, как правило, уже включены в вашу поставку Python (будь то Linux, FreeBSD или даже Windows) и не требуют дополнительной инсталляции. Как вы видели в конце прошлого урока, модуль подключается оператором import. В качестве параметров вы можете указать любое количество модулей. Также допускается любое число операторов import в любой точке вашей программы.

Для чего же нужны модули? Чуть позже, когда мы напишем свою функцию, вы увидите, что с помощью модуля очень легко реализуется концепция повторного использования кода. Пока же модули интересны нам как способ расширения возможностей вашей программы. С их помощью вы подключаете уже написанные кем-то наборы функций и методов, которые сможете использовать почти так же, как если бы они были встроенными (такими, как рассмотренная нами ранее float()).

Начнем с модуля sys. В нем определен ряд переменных, содержащих информацию об операционной системе, дескрипторы стандартных потоков ввода, вывода и ошибок (stdin, stdout и stderr соответственно), и так далее. рассмотрим небольшой пример:

>>> import sys
>>> print sys.arch, sys.platform
 i386 linux2
>>> print sys.version
 2.4.1 (#1, Sep 13 2005, 00:39:20)
 [GCC 4.0.2 20050901 (prerelease) (SUSE Linux)]
>>> print sys.maxint
 2147483647

Как видите, чтобы получить доступ к определённым в модуле переменным (впрочем, это относится и к остальным объектам), перед их именем следует указать имя модуля. Это оберегает от конфликта имён, когда объявленная вами переменная или функция имеет такое же имя, как и определенная в модуле. то есть каждый модуль имеет свое пространство имен, доступ к которому осуществляется по имени модуля. Если имя модуля слишком неудобно для работы, вы можете указать для него псевдоним после ключевого слова as (например, import SimpleXMLRPCServer as rpc), и в дальнейшем использовать это упрощённое имя. Впрочем, иногда удобнее (а порой и необходимо), что-бы имена, определенные в модуле, были импортированы непосредственно в пространство имён основной программы. Для этого предусмотрена несколько иная конструкция:

>>> from sys import *
>>> print platform
 linux2

Теперь можно обращаться к объектам модуля непосредственно, но будьте осторожны – вы потеряете все определённые вами переменные и функции, имена которых совпадут с именами определенных в модуле.


Символ «звездочка» в операторе from - import означает, что должно быть импортировано всё, что определено в модуле. Вы также можете перечислить только то, что желаете сделать доступным в вашей программе (например, from sys import version).

Ещё одна важнейшая переменная модуля sys – список sys.argv, в который в момент запуска Python-программы помещаются аргументы, переданные в командной строке. Пример использования этого списка вы увидите далее в данной статье.

[править] Модуль os

Пожалуй, самый популярный модуль Python – это os. Он предоставляет вам ряд функций, позволяющих взаимодействовать с операционной системой: chroot(), mkdir(), setuid() и так далее. Названия, думаю, говорят сами за себя. а как посмотреть полный список функций, доступных в модуле, я надеюсь, вы ещё помните с прошлого урока: dir(os).

Для работы с файловой системой практически незаменим подмодуль этого модуля – os.path. С его помощью вы можете определять типы файлов, установленные для них права доступа, и тому подобное. Нам ещё доведётся поработать с ним на практике.

[править] Прочие модули

Вообще, в стандартную поставку Python входит несколько десятков наиболее полезных модулей. Найти их можно в каталоге /usr/lib/python (на некоторых системах путь может быть иным, например, /usr/local/lib/python). Если быть точнее, то Python ищет свои модули в каталогах, список которых возвращает переменная sys.path.

Обращайте внимание на файлы с расширением py (pyc и pyo – это байт-код модулей, который используется для экономии ресурсов, поскольку при обращении к модулю повторная компиляция не требуется). Названия большинства из них говорят сами за себя, к тому же вы можете открыть любой модуль, чтобы ознакомиться с его кодом и, как правило, очень подробными комментариями. С некоторыми из них мы обязательно столкнёмся в дальнейшем.

[править] Функции

Со встроенными функциями вы уже знакомы. Но что делать, если возможностей, заложенных в интерпретатор или стандартные модули, вам недостаточно? Всё просто – напишите собственную функцию!

Пользовательская функция определяется оператором def (от define – определять). В качестве параметра указывается имя функции (оно должно быть уникально в пределах пространства имён основной программы), а в скобках перечисляются её формальные аргументы. Далее ставится двоеточие (как и в случае любых блочных операторов, таких как if или for), и на последующих строках, имеющих отступ, вводится код функции. Впрочем, когда речь идёт о Python, несколько строк кода способны сказать больше, чем пол-страницы текста на естественном языке. Чтобы лучше во всем разобраться, рассмотрим один пример (файл назовем abbr.py):

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
 Программа обслуживает небольшой словарь сокращений, используя anydbm
"""
import sys, anydbm as db
dictfile = 'dict.dbm'
def openDictionary(dbmfile=dictfile):
     """ Открыть словарь """
     global dictionary
     try:
         dictionary = db.open(dbmfile, 'c')
     except:
         raise 'Ошибка открытия файла'
def getMeaning(abbr):
     """ Поиск расшифровки """
     try:
 
        return dictionary[abbr]
     except:
        return '[не определено]'
def addMeaning(abbr, meaning):
     """ Добавить сокращение """
     dictionary[abbr] = meaning
    def delMeaning(abbr):
     """ Удалить сокращение """
     try:
        del dictionary[abbr]
     except:
        pass
if __name__ == "__main__":
     openDictionary()
     try:
        command = sys.argv[1]
        if command == '-a':
            addMeaning(sys.argv[2], sys.argv[3])
        elif command == '-d':
            delMeaning(sys.argv[2])
        else:
            abbr = sys.argv[1]
            print abbr + ' = ' + getMeaning(abbr)
     except:
        print """\
 Неверные аргументы. Допустимый синтаксис:
 abbr.py <ABBR>                  - расшифровать сокращение
 abbr.py -a <ABBR> <MEANING>     - добавить расшифровку
 abbr.py -d <ABBR>                - удалить сокращение
 """
 else:
     openDictionary()

Эта программа реализует простейший консольный словарь сокращений. Только не забудьте сделать файл исполняемым (chmod u+x abbr.py). Поддерживаются три операции (информацию об этом вы получите, если попытаетесь вызвать сценарий с неправильными аргументами):

  1. abbr.py – возвращает из словаря расшифровку сокращения <ABBR>;
  2. abbr.py -a <ABBR> <MEANING> – добавляет в словарь расшифровку сокращения. В силу особенностей словарного типа данных в Python, эта же команда изменяет расшифровку для уже существующей аббревиатуры;
  3. abbr.py -d <ABBR> – удаляет из словаря запись для указанного сокращения.

Обратите внимание на вторую строку – здесь указывается кодировка исходного текста (подробности см. на странице http://www.python.org/peps/pep-0263.html). Если вы используете не UTF-8, то укажите в этой строке свою кодировку (например, koi8-r).

Строки, обрамлённые утроенными кавычками, в данном случае можно рассматривать как многострочные комментарии.

Оператор global в функции openDictionary() делает переменную dictionary доступной за пределами функции. В противном случае её действие распространялось бы только на эту функцию. Ещё один интересный момент – то, как описан формальный аргумент функции. В данном случае мы задаем для переменной значение по умолчанию. Если в дальнейшем при вызове функции вы не передадите в неё аргумент, будет использовано значение переменной dictfile.

Несколько слов нужно сказать о самом модуле anydbm. С его помощью Python выполняет поиск доступного dbm-пакета в текущей системе (вам не нужно об этом беспокоиться). Данные в файле DBM организованы по словарному принципу (ключ – значение), поэтому данный файл может быть естественным образом сопоставлен с переменной типа «словарь». Все дальнейшие операции с данными словаря для программиста выглядят как обычные, а dbm-модуль позаботится о том, чтобы все данные оказались сохранены в файл. Собственно говоря, dbm-файл вы можете рассматривать как словарь, содержимое которого не теряется между запусками программы. также обратите внимание, что при подключении этого модуля мы используем псевдоним.

Итак, в функции openDictionary() мы открываем файл dict.dbm (второй параметр – 'c' – даёт указание создать такой файл, если его ещё нет) и сопоставляем его со словарём dictionary. Конструкция «try – except» служит для обработки ошибок. В блок try мы помещаем потенциально опасные операции (которые могут завершиться с ошибкой), а блок except содержит код, который будет выполнен в случае возникновения ошибки в блоке try. Оператор raise генерирует сообщение об ошибке и прерывает выполнение программы.

Далее описаны три функции, реализующие заявленную выше функциональность. Пожалуй, в пояснении нуждается здесь только оператор pass в функции delMeaning(): это пустой оператор, который ничего не делает – если нужного ключа в словаре нет, то и удалять нечего.

Ну и в конце сценария, в секции оператора if, вы можете увидеть пример обработки аргументов командной строки.

Конечно, этот учебный пример не лишён недостатков: невозможно сделать несколько записей, имеющих одинаковую аббревиатуру, работа чувствительна к регистру символов (введя запись для «UDP», вы не сможете получить значение по ключу «udp»), и т.д. Однако сейчас нам важен не функционал, а собственно языковые конструкции.

[править] Возвращаясь к модулям

Итак, мы написали функцию, которая может оказаться крайне полезной в других программах. Как бы было хорошо, если бы оказалось возможным поместить её в модуль! А ведь нет ничего проще – она уже в модуле. Да-да! Вы можете просто подключить написанную выше программу в качестве модуля (одним из операторов, import или fromimport) и спокойно использовать определённые в ней переменные и функции!

В этом заключается одно из преимуществ Python по сравнению с его «прямым конкурентом» - языком Perl. В Perl вам пришлось бы специально оформлять вашу программу как модуль (как минимум, потребуется оператор package). В Python концепция повторного использования кода заложена в основу синтаксиса и не требует от вас совершенно никаких усилий.

Рассмотрим пример:

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import abbr
abbr.delMeaning('UDP')
print abbr.getMeaning('IP')

Как видите, вам достаточно импортировать py-программу (расширение не указывается), и вы можете в полной мере воспользоваться всем созданным ранее. Единственное, этот файл должен быть доступен для поиска (самый простой вариант – поместить его в текущий каталог).

Обратите внимание, что в момент импортирования переменная __name__ в подключаемом модуле будет иметь значение, совпадающее с именем модуля. Поэтому в данном случае вместо секции if сценария abbr.py будет выполнена секция else. Подобный оператор if – else присутствует практически в каждой программе на языке Python и позволяет использовать ее и как модуль, и как самостоятельный сценарий (в последнем случае, как нетрудно догадаться, переменная __name__ будет иметь значение "__main__").

Итак, вы уже в состоянии разрабатывать довольно серьёзные и полезные программы. Однако не научившись работать с классами, вы не познаете всю мощь Python. В следующий раз мы заполним и этот пробел.

Персональные инструменты
купить
подписаться
Яндекс.Метрика