Модераторы: pythonwin, Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> переводим Python FAQ, на русский язык 
:(
    Опции темы
setq
Дата 23.10.2005, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 707
Регистрация: 28.9.2003

Репутация: 19
Всего: 26



из Programming FAQ

1.2.5 Как передать дополнительные или именованные параметры (optional or keyword parameters) из одной функции в другую?

Получить такие параметры можно с помощью спецификаторов * и ** в списке аргументов функции; они возвращают кортеж позиционных аргументов и словарь именованых параметров. После этого Вы можете передать их в другую функцию используя в её вызове * и **:

Код
def f(x, *tup, **kwargs):
        ...
        kwargs['width']='14.3c'
        ...
        g(x, *tup, **kwargs)


В случае если Вас беспокоит совместимость с версиями ниже 2.0, используйте 'apply':

Код
def f(x, *tup, **kwargs):
        ...
        kwargs['width']='14.3c'
        ...
        apply(g, (x,)+tup, kwargs)


Это сообщение отредактировал(а) setq - 25.10.2005, 19:27
PM MAIL   Вверх
srd
Дата 23.10.2005, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


Профиль
Группа: Участник Клуба
Сообщений: 951
Регистрация: 30.8.2003
Где: Владивосток

Репутация: 7
Всего: 49



1.4.1. Почему в Питоне для группировки инструкций используется выравнивание?

Guido van Rossum считает, что использование выравнивания для группировки очень элегантно, и делает обычные программы на Питоне более ясными. Большинству людей через некоторое время начинает нравиться эта особенность.

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

if (x <= y)
        x++;
        y--;
z++;

Если условие истинно, то выполняется только инструкция x++, но выравнивание заставляет вас верить в обратное. Даже опытные программисты на Си иногда могут потратить много времени, разбираясь, почему y уменьшается на единицу даже если x > y.

Благодаря отсутствию начальных/конечных скобок Питон гораздо меньше способствует появлению конфликтов в выборе стиля кодирования. В Си можно размещать скобки самым разным образом. Если вы читаете и пишете код, использующий один стиль, вы будете испытывать неудобства в восприятии кода (или от требования писать код) с другим стилем.

Многие стили кодирования требуют для скобок отдельных строк кода. Это делает программы длиннее, тратит экранное пространство, затрудняет обзор программы. В идеальном случае функция должна помещать в экран (примерно 20-30 строк). 20 строк кода на Питоне могут выполнять гораздо больше работы, чем 20 строк кода на Си. Это не только благодаря отсутствию скобок, но и благодаря отсутствию объявлений и благодаря типам данных высокого уровня. Но синтаксис, основанный на выравнивании, здесь действительно помогает.

1.4.2. Почему вычисления с плавающей точкой такие неточные?

Люди часто удивляются результатам вида:
Код

>>> 1.2-1.0
0.199999999999999996

и думают, что это какая-то ошибка в Питоне. Это не ошибка. Проблема вызвана внутренним представлением чисел с плавающей точкой, использующим ограниченное количество двоичных цифр для представления десятичного числа. Некоторые десятичные числа не могут быть точно представлены в двоичном виде. В результате появляются небольшие ошибки округления.

В десятичной математике существует много чисел, которые не могут быть представлены конечным числом десятичных чисел, например 1/3 = 0.3333333333.......

Если основание равно двум, то 1/2 = 0.1, 1/4 = 0.01, 1/8 = 0.001 и так далее. 0.2 = 2/10 = 1/5,
Получается двоичное дробное число 0.001100110011001…

Числа с плавающей точкой имеют только 32 или 64 бита точности. Т.е. цифры с некоторой позиции обрезаются, и конечное десятичное число будет выглядеть как 0.199999999999999996, а не 0.2

Функция repr() выводит такое количество цифр, которое необходимо для того, чтобы выражение eval(repr(f)) == f было истинным для любого f с плавающей точкой. Функция str() выводит меньше цифр, что приводит к менее осмысленным результатам, чем ожидалось:
Код

>>> 0.2
0.20000000000000001
>>> print 0.2
0.2

Опять-таки, подобные проблемы появляются не из-за самого Питона, а из-за того, как лежащая в основе Си-платформа представляет числа с плавающей точкой, и, в конечном счёте, из-за неточностей, которые вы получаете, когда записываете числа как строки с конечным числом цифр.

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

epsilon = 0.0000000000001 # Tiny allowed error
expected_result = 0.4

if expected_result-epsilon <= computation() <= expected_result+epsilon:
   ...

Пожалуйста, прочитайте раздел, посвящённый арифметике с плавающей точкой, в учебном пособии по Питону, для получения более подробной информации.

===
добавлено setq: в версии Питона 2.4 появился модуль Decimal, предназначеный для решения проблем, связаных с неточностью десятичных вычислений

Это сообщение отредактировал(а) setq - 23.10.2005, 11:39


--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
setq
Дата 24.10.2005, 22:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 707
Регистрация: 28.9.2003

Репутация: 19
Всего: 26



из Programminf FAQ

1.7.5 Когда я редактирую импортированный модуль а затем перезагружаю его, изменения невидны. Почему?

Из соображений эффективности а также стабильности (consistency) Питон прочитывает модуль только во время первого импорта. В противном случае, в программе состоящей из многих модулей, где каждый модуль подгружает один и тот же базовый модуль, базовый модуль разбирался бы (parsed and re-parsed) (*) много раз. Чтобы явно переимпортировать изменённый модуль, делайте так:

Код
import modname
reload(modname)


Осторожно: этот способ не на 100% fool-proof. В частности, модули, которые содержат утверждения:

Код
from modname import some_objects


продолжат работать со старыми версиями импортированных объектов. Если в модуле есть определение класса, существующие экземпляры этого класса не будут updated на использование нового определения класса. Это может привести к следующему парадоксальному поведению:

Код
>>> import cls
>>> c = cls.C()                # создать экземпляр класса C
>>> reload(cls)
<module 'cls' from 'cls.pyc'>
>>> isinstance(c, cls.C)       # не является экземпляром C?!?
False


Суть проблемы становится ясной, если Вы распечатаете класс объекта:

Код
>>> c.__class__
<class cls.C at 0x7352a0>
>>> cls.C
<class cls.C at 0x4198d0>




(*) "parsed and re-parsed" -- так и хотелось написать "парсился бы и перепарсивался бы" smilesmilesmile
PM MAIL   Вверх
setq
Дата 25.10.2005, 17:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 707
Регистрация: 28.9.2003

Репутация: 19
Всего: 26



из Programming FAQ

1.3.5 Как изменить строку в памяти (in place)?

Никак, потому что строки неизменяемы. Если Вам нужен объект с таким свойством, попробуйте преобразовать строку в список или воспользуйтесь модулем array:

Код
>>> s = "Hello, world"
>>> a = list(s)
>>> print a
['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']
>>> a[7:] = list("there!")
>>> ''.join(a)
'Hello, there!'

>>> import array
>>> a = array.array('c', s)
>>> print a
array('c', 'Hello, world')
>>> a[0] = 'y' ; print a
array('c', 'yello world')
>>> a.tostring()
'yello, world'


1.3.6 Как вызвать функцию/метод имя которого сохранено в строке?

Способов несколько.

Лучший из них - использование отображения (dictionary) строк в функции. Главным достоинством этой техники является то, что строкам не обязательно быть именами функций. Это также основной способ для имитации конструкции case:

Код
def a():
    pass

def b():
    pass

dispatch = {'go': a, 'stop': b}  # Внимание: имена функций записаны
                                 #  без завершающих круглых скобок

dispatch[get_input()]()  # Внимание: завершающие круглые скобки
                         #  вызывают функцию


Встроенная функция getattr():

Код
import foo
getattr(foo, 'bar')()


getattr() применима к любому объекту, включая классы, экземпляры классов, модули и т.д

В стандартной библиотеке можно найти нечто в этом роде:

Код
class Foo:
    def do_foo(self):
        ...

    def do_bar(self):
        ...

 f = getattr(foo_instance, 'do_' + opname)
 f()


Можно также использовать locals() или eval() для нахождения функции по имени:

Код
def myFunc():
    print "hello"

fname = "myFunc"

f = locals()[fname]
f()

f = eval(fname)
f()


Осторожно: eval() - медленная и опасная функция. Если Вы не проверяете строку, то кто-то манипулируя с вводом сможет запустить на исполнение любую функцию.

Это сообщение отредактировал(а) setq - 25.10.2005, 17:33
PM MAIL   Вверх
setq
Дата 25.10.2005, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 707
Регистрация: 28.9.2003

Репутация: 19
Всего: 26



из Programming FAQ

1.4.5 Как создать в Питоне массив?

Используйте список:

Код
["this", 1, "is", "an", "array"]


Списки эквивалентны по скорости (in their time complexity) массивам в C или Pascal (обсуждается здесь); основное различие в том, что питоновские списки могут содержать в себе объекты разных типов.

Модуль array позволяет создавать массивы определённого типа с компактным хранением (compact representations), но такие массивы индексируются медленнее, чем списки (*). Кроме того такие расширения как Numeric также определяют похожие на массивы структуры с разнообразными свойствами.

Чтобы получить списки в стиле Lisp можно эмулировать cons-ячейки с помощью кортежей:

Код
lisp_list = ("like",  ("this",  ("example", None) ) )


Если Вам требуется mutability - можете использовать списки вместо кортежей. Аналогом car в lisp будет lisp_list[0], а аналогом cdr - lisp_list[1]. Но используйте это только если Вам такие списки в самом деле нужны, потому что обычно это намного медленнее, чем using питоновские списки.

1.4.6 Как создать многомерный список (multidimensional list)?

Вы наверно пытались сделать многомерный массив как-то вроде этого:

Код
A = [[None] * 2] * 3


Если его распечатать, то кажется, будто всё в порядке:

Код
>>> A
[[None, None], [None, None], [None, None]]


Но если Вы добавляете в него значение, оно появляется в нескольких местах:

Код
>>> A[0][0] = 5
>>> A
[[5, None], [5, None], [5, None]]


Дело в том, что повторение списка с помощью * не создаёт копий, оно создаёт только ссылки на уже существующие объекты. *3 создаст список, содержащий 3 ссылки на один и тот же список длиной в 2 элемента. Изменения произведённые над одной строкой затронут все строки, а это почти наверняка не то что Вы хотели.

Предлагаемое решение - сначала создать список нужной длинны, а затем заполнить его списками (создаваемыми заново):

Код
A = [None]*3
for i in range(3):
     A[i] = [None] * 2


Этот код сгенерирует список из 3 различных списков длиной в 2 элемента. Вы можете также использовать list comprehension:

Код
w,h = 2,3
A = [ [None]*w for i in range(h) ]


Или воспользоваться расширением, предоставляющим такой тип как matrix; самое известное: Numeric Python.


(*) "но такие массивы индексируются медленнее, чем списки" -- что, правда? интересно, засчёт чего?

Это сообщение отредактировал(а) setq - 26.10.2005, 09:23
PM MAIL   Вверх
setq
Дата 27.10.2005, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 707
Регистрация: 28.9.2003

Репутация: 19
Всего: 26



1.2.12 Можно ли на Питоне составить выражение, которое трудно прочитать (obfuscated one-liners)?

Да. Обычно, это делается вкладыванием lambda-функций в lambda-функции. Вот 3 примера due to Ulf Bartelt:

Код
# Простые числа < 1000
print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,
map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))

# Первые 10 чисел Фибоначчи
print map(lambda x,f=lambda x,f:(x<=1) or (f(x-1,f)+f(x-2,f)): f(x,f),
range(10))

# Множество Мандельброта
print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,
Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,
Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,
i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y
>=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(
64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy
))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24)
#    \___ ___/  \___ ___/  |   |   |__ строк на экране
#        V          V      |   |______ колонок на экране
#        |          |      |__________ максимум "итераций"
#        |          |_________________ range on y axis
#        |____________________________ range on x axis


Don't try this at home, kids! (*)


1.3 Числа и строки

1.3.1 Как определять шестнадцатиричные и восьмиричные целые?

Чтобы задать восьмеричное целое поставьте перед числом 0. Например, чтобы присвоить в "a" восьмеричное значение "10" (8 в десятичном счислении), введите:

Код
>>> a = 010
>>> a
8


Шестнадцатиричные числа задаются так же просто. Поставьте перед значением 0, а затем строчную или прописную "x". Шестнадцатиричные цифры могут быть как в нижнем так и в верхнем регистре. Например, наберите в интерпретаторе:

Код
>>> a = 0xa5
>>> a
165
>>> b = 0XB2
>>> b
178


1.3.2 Почему -22 / 10 возвращает -3?

В первую очередь это продиктовано желанием иметь для i%j тот же знак что и у j. Если Вам нужно именно такое поведение % и в то же время Вы хотите чтобы соблюдалось:

Код
i == (i/j)*j + (i%j)


в таком случае целочисленное деление должно возвращать наименьшее целое (floor). Язык C также предполагает истинность этого равенства, и поэтому компиляторы, которые truncate i/j (**) должны сохранить для i%j тот же знак что и у числа i.

В действительности, существует не так много случаев, когда нужно вычислить i%j при отрицательном j. Когда j положительное, такие случаи есть и фактически в каждом из них выгоднее чтобы i%j было >= 0. Допустим, если на часах 10, то сколько на них было 200 часов назад? -190 % 12 == 2 даёт полезный результат, а -190 % 12 == -10 - притаившийся в засаде баг.

1.3.3 Как преобразовать строку в число?

Для целых чисел используйте встроенный конструктор int(), например int('144') == 144. Аналогично, float() осуществляет преобразование в число с плавающей запятой, например float('144') == 144.0.

По умолчанию, эти конструкторы интерпретируют числа в десятичной системе, поэтому int('0144') == 144, а int('0x144', 16) возбуждает исключение ValueError. int(string, base) использует второй необязательный аргумент как базу счисления, поэтому int('0x144', 16) == 324 (***). Если аргумент base равен нулю, число интерпретируется исходя из правил Питона: ведущий '0' означает восьмеричную, а '0x' шестнадцатиричную константу.

Не используйте встроенную функцию eval() если всё что Вам нужно это преобразовать строку в число. потому что eval() выполняется значительно медленнее и может представлять проблему безопасности: кто-то может передать Вам питоновское выражение с нежелательным побочным действием (unwanted side effects). Например, выполнение __import__('os').system("rm -rf $HOME") удалит всё в вашей домашней директории.

eval() интерпретирует числа как выражения Питона, поэтому например eval('09') выдаёт синтаксическую ошибку так как Питон считает числа начинающиеся c '0' восьмеричными (база == 8).

1.3.4 Как преобразовать число в строку?

Чтобы преобразовать например число 144 к строке '144', используйте встроенную функцию str(). Если Вы хотите шестнадцатиричное или восьмеричное представление, используйте встроенные функции hex() и oct(). Для продвинутого (fancy) форматирования используйте строковую операцию %, например "%04d" % 144 вычислится в '0144', а "%.3f" % (1/3.0) - в '0.333'. Загляните в руководство по стандартной библиотеке чтобы почитать об этом подробнее.


(*) вот что получилось у меня:
Код
BBBBBBBBBBBBBBBCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDCCCCCCCCCCCCCCC
BBBBBBBBBBBBBCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEFGJJHFFFEEEEEDDDDDCCCCCCCCCC
BBBBBBBBBBBCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEFFFGHJPJKL_FEEEEEEDDDDDDDCCCCC
BBBBBBBBBCCCCCCDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEFFFFGHIJZR_QJIGFFFEEEEEEDDDDDDDCC
BBBBBBBBCCCCDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEFFFGGGHIKP______SKHGFFFFFEEEEDDDDDDD
BBBBBBBCCCDDDDDDDDDDDDDDDDDDDDEEEEEEEEEFFFHHIXIIIIJKLO______NKJJIHGGGHSGFEEDDDDD
BBBBBBCCDDDDDDDDDDDDDDDDDDDEEEEEFFFFFFFGGHIM___R_________________PLN[SQXIFEEDDDD
BBBBBCDDDDDDDDDDDDDDDDEEEFFFFFFFFFFFGGGHIKMNS_________________________UIGGFEEDDD
BBBBBDDDDDDDDDDEEEEEFFGHOIHHHHHHHHHHHHIJLP____________________________RKJPGFEEDD
BBBBDDDDEEEEEEEEEFFFFGGHJM___LNW_ONKJJKNY______________________________SKHGFEEED
BBBBDEEEEEEEEEFFFFFFGHHJLOT__________QPZ_________________________________HFFEEEE
BBBDEEEEEEEFGGGGHHHJM_QNS______________________________________________[HGFFEEEE
BBB_________________________________________________________________QLIHGFFFEEEE
BBBDEEEEEEEFGGGGHHHJM_QNS______________________________________________[HGFFEEEE
BBBBDEEEEEEEEEFFFFFFGHHJLOT__________QPZ_________________________________HFFEEEE
BBBBDDDDEEEEEEEEEFFFFGGHJM___LNW_ONKJJKNY______________________________SKHGFEEED
BBBBBDDDDDDDDDDEEEEEFFGHOIHHHHHHHHHHHHIJLP____________________________RKJPGFEEDD
BBBBBCDDDDDDDDDDDDDDDDEEEFFFFFFFFFFFGGGHIKMNS_________________________UIGGFEEDDD
BBBBBBCCDDDDDDDDDDDDDDDDDDDEEEEEFFFFFFFGGHIM___R_________________PLN[SQXIFEEDDDD
BBBBBBBCCCDDDDDDDDDDDDDDDDDDDDEEEEEEEEEFFFHHIXIIIIJKLO______NKJJIHGGGHSGFEEDDDDD
BBBBBBBBCCCCDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEFFFGGGHIKP______SKHGFFFFFEEEEDDDDDDD
BBBBBBBBBCCCCCCDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEFFFFGHIJZR_QJIGFFFEEEEEEDDDDDDDCC
BBBBBBBBBBBCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEFFFGHJPJKL_FEEEEEEDDDDDDDCCCCC
BBBBBBBBBBBBBCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEFGJJHFFFEEEEEDDDDDCCCCCCCCCC

красота ))

(**) "truncate i/j" -- я так понял это означает "берут у i/j все цифры до десятичной точки", советовался у нас на работе с математиками - они вроде подтверждают. но я не на 100% уверен.

(***) "int('0x144', 16) == 324" -- равно как и int('144', 16)

Это сообщение отредактировал(а) setq - 27.10.2005, 12:39
PM MAIL   Вверх
srd
Дата 27.10.2005, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


Профиль
Группа: Участник Клуба
Сообщений: 951
Регистрация: 30.8.2003
Где: Владивосток

Репутация: 7
Всего: 49



1.4.3. Почему строки в Питоне не изменяемы?

Тому есть несколько причин.

Во-первых, производительность. В следствие неизменяемости строк становится возможным размещать их эффективно в памяти в момент создания, что согласуется с требованиями к постоянным неизменяемым хранилищам данных.

Во-вторых, в Питоне строка считается таким же простейшим типом, как и число. Ничто не может превратить значение 8 во что-то другое. И в Питоне ничто не может превратить строку «восемь» во что-то ещё.

1.4.4. Почему использование self должно быть явным в определениях и вызовах методов?

Эта идея была заимствована из Модулы-3, и она оказалась очень полезной по нескольким причинам:

Во-первых, это делает более понятным то, что вы используете метод или атрибут экземпляра, а не локальную переменную. При чтении self.x и self.meth() становится абсолютно понятно, что это переменная экземпляра и метод, даже если вы не знаете определение класса наизусть. В Си++ вы можете это понять по отсутствию объявления локальной переменной (предположим, что глобальные переменный малочисленны и легко узнаваемы), но в Питоне объявлений локальных определений не существует, потому для уверенности вы должны были бы искать определение класса. Некоторые стандарты кодирования для Си++ или Явы требуют использования префикса m_ для атрибутов экземпляра, т.е. подобная ясность полезна и в этих языках.

Во-вторых, это означает, что для ссылки или вызова метода из конкретного класса не нужен специальный синтаксис. В Си++ для использования метода базового класса, переопределённого в производном классе, используется оператор ::, а в Питоне вы можете написать baseclass.methodname(self, <список аргументов>). Это особенно полезно для вызова метода __init__() и в случае, если метод производного класса хочет расширить метод базового класса с тем же именем, и для этого каким-либо образом его вызывает.

Наконец, это решает синтаксическую проблему с присваиванием переменным экземпляра. Т.к. в Питоне локальные переменные – это переменные, которым присвоено значение в теле функции, и которые не объявлены глобальными явно, то должен быть аналогичный способ указать интерпретатору, что инструкция присваивания означает присваивание переменной экземпляра, а не локальной переменной, и способ должен быть синтаксическим (по соображениям эффективности). В Си++ используются объявления, а в Питоне объявлений нет, и было бы нежелательно их вводить только ради этой цели. Явное использование self.var прекрасно с этим справляется. Также явное написание «self.var» для переменных экземпляра означает, что для ссылки на неквалифицированные имена внутри метода не нужен поиск в instance’s directories (директориях экземпляра?). Другими словами, локальные переменные и переменные экземпляра живут в двух разных пространствах имён, и вы должны указать Питону, какое пространство имён использовать.

1.4.5. Почему я не могу в выражениях использовать присваивание?

Многие люди, работавшие с Си или Perl, жалуются на то, что они хотели бы использовать идиому Си:
Код

while (line = readline(f)) {
    … делаем что-то…
}

но в Питоне вынуждены писать так:
Код

while True:
    line = f.readline()
    if not line:
        break
    …делаем что-то…

Причиной запрета присваивания в выражениях является распространённая и плохо обнаруживаемая в других языках ошибка, к которой приводит следующая инструкция:
Код

if (x = 0) {
    ...обработка ошибок...
}
else {
    ...код, работающий только с ненулевым значением x...
}

Это обычная опечатка: было написано x = 0, присваивание 0 переменной x, когда хотели сравнение x == 0.

Было предложено множество вариантов, большинство из которых использовало произвольный или загадочный синтаксис или ключевые слова, что нарушало простое требование к предложениям по изменению языка: конструкция должна быть интуитивно понятной для человека, ещё с ней не знакомой.

Интересно, что наиболее опытные программисты на Питоне распознают идиому «while True» и не особо скучают по отсутствию присваивания в выражениях. Только новички испытывают сильное желание добавить эту возможность в язык.

Есть другой вариант, выглядящий привлекательно, но менее ясный, чем решение «while True»:
Код

line = f.readline()
while line:
    ...здесь что-то делаем...
    line = f.readline()

Проблема в том, что если вы захотите изменить способ получения следующей строки (например, захотите использовать sys.stdin.readline()), то вам потребуется внести изменения в двух участках вашей программы, и второе вхождение скрыто в конце цикла.

Лучшим подходом будет использование итераторов, позволяющих перебирать объекты с помощью инструкции for. Например, в текущей версии Питона файловые объекты поддерживают итераторы, и вы можете теперь просто писать:
Код

for line in f:
    ... здесь что-нибудь делаем...


1.4.6. Почему для одной функциональности используются методы (например list.index()), а для другой – функции (например len(list))?

В основном по историческим причинам. Функции используются для тех операций, которые являются общими для группы типов, и которые применимы к объектам, вообще не имеющим методов (например, кортежи). Если вы используете функциональные свойства Питона (map(), apply() и т.д.), то удобно иметь функцию, применимую к аморфным коллекциям объектов.

На самом деле, реализация len(), max(), min() как встроенных функций займёт меньше кода, чем реализация их как методов для каждого отдельного типа. Кто-то может спорить о частных случаях, но это часть Питона, и уже поздно делать такие фундаментальные изменения. Функции оставлены во избежание множества нарушений в коде.

Обратите внимание, что операции над строками в Питоне перемещены из внешних функций (модуль string) в методы. Но len() осталась функцией.



--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
setq
Дата 28.10.2005, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 707
Регистрация: 28.9.2003

Репутация: 19
Всего: 26



1.2.1 Как из функции получить доступ к глобальной переменной?

Вы пытаетесь сделать нечто подобное?

Код
x = 1 # make a global

def f():
      print x # try to print the global
      ...
      for j in range(100):
           if q>3:
              x=4


Любая переменная, которой присваивается значение внутри функции считается локальной. Поскольку в последней строчке x связывается со значением, компилятор (*) полагает, что x локальная переменная. Следовательно print x пытается напечатать неинициализированную локальную переменную, что результируется в NameError (**).

Решение: вставить явное объявление global в начале функции:

Код
def f():
      global x
      print x # try to print the global
      ...
      for j in range(100):
           if q>3:
              x=4


Теперь любое упоминание x будет интерпретироваться как ссылка на x из пространства имён модуля.

1.2.2 Как определяются локальные и глобальные переменные в Питоне?

В Питоне переменные, которые упоминаются в теле функции [но им ничего не присваивается] - глобальные. Если переменной присваивается новое значение где-либо в функции, она считается локальной (***). Если Вы хотите изменить глобальную переменную, Вы должны объявить её явно с помощью 'global'.

Хотя это [выборочное объявление global] сначала кажется странным, всё проясняется если немного поразмыслить. С одной стороны, требование явного объявления global для всех имён, которым присваиваются значения, позволяет защититься от нежелательного побочного эффекта. С другой - если бы global был нужен для всех ссылок на глобальные имена, Вам пришлось бы использовать его всё время. Вам пришлось бы объявлять как global все встроенные функции и компоненты (component) импортированных модулей. Подобный хаос свёл бы на нет всю пользу от использования global как средства для защиты от побочных эффектов.

1.2.3 Как организовать совместный доступ к глобальным переменным для нескольких модулей?

Канонический способ организовать подобный доступ - это создать отдельный модуль (часто называемый config или cfg). Просто добавьте import config в каждый модуль Вашего приложения; при этом модуль становится доступен через глобальное имя. Поскольку существует только один экземпляр модуля, любые изменения произведённые в модуле отражаются везде. Например:


config.py:

Код
x = 0   # Default value of the 'x' configuration setting


mod.py:

Код
import config
config.x = 1


main.py:

Код
import config
import mod
print config.x


По тем же соображениям, модули можно использовать как основу для имплементации Singleton design pattern.


(*) "компилятор" -- компилятор?!!
(**) "результируется в NameError" -- в моём случае выбрасывается UnboundLocalError (python 2.4.2)
(***) вероятно чтобы подчеркнуть всю важность этого утверждения, автор решил повторить его дважды. )) думаю, это лишнее.

Это сообщение отредактировал(а) setq - 28.10.2005, 14:08
PM MAIL   Вверх
setq
Дата 28.10.2005, 22:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 707
Регистрация: 28.9.2003

Репутация: 19
Всего: 26



1.2.8 Как в Питоне получить копию объекта?

В большинстве случаев подойдёт copy.copy() или copy.deepcopy(). Не любой объект можно скопировать, но большинство - можно.

Некторые объекты копируются проще. У словарей есть метод copy():

Код
newdict = olddict.copy()


Последовательности можно копировать взятием среза:

Код
new_l = l[:]


1.2.9 Как узнать методы и атрибуты объекта?

Для x - экземпляра пользовательского класса - вызов dir(x) возвращает отсортированный в алфавитном порядке список аттрибутов x а также методов и атрибутов, принадлежащих классу.
PM MAIL   Вверх
srd
Дата 31.10.2005, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


Профиль
Группа: Участник Клуба
Сообщений: 951
Регистрация: 30.8.2003
Где: Владивосток

Репутация: 7
Всего: 49



1.4.7. Почему join() является методом строки, а не списка или кортежа?

В Питоне версии 1.6 для строк были добавлены методы, предоставляющие ту же функциональность, что и функции в модуле string. Теперь строки на много более похожи на другие стандартные типы. Использование большинства этих методов стало широко распространённым. Но один из них заставляет некоторых программистов чувствовать себя некомфортно:
Код

", ".join(['1', '2', '4', '8', '16'])

Результатом выполнения строки кода выше будет:
Код

"1, 2, 4, 8, 16"

Против подобного кода обычно приводят два аргумента.

Первый звучит так: «Это действительно странно применять метод к строковому литералу (строковой константе)». На что можно ответить, что строковой литерал – это просто постоянное значение. Не существует логичного объяснения, почему можно применять методы к идентификаторам, связанными со строками, но нельзя делать тоже с литералами.

Второе возражение обычно звучит так: «Операция объединения членов последовательности в строковую константу должна применяться к ПОСЛЕДОВАТЕЛЬНОСТИ». На самом деле нет. По некоторым причинам гораздо меньше трудностей возникаем с использованием split() как строковым методом. Здесь легче увидеть, что
Код

"1, 2, 4, 8, 16".split(", ")

предписывает символьному литералу вернуть список подстрок, полученный с использованием указанного разделителя (по умолчанию – пробел). Тогда строка в UNICODE вернёт список строк в UNICODE, а строка в ASCII вернёт список строк в ASCII, и все будут счастливы.

join() является строковым методом, потому что этот метод предписывает строке-разделителю перебрать элементы последовательности, получить символьное представление каждого элемента, и между ними вставить себя. Этот метод может быть использован с любыми аргументами, которые удовлетворяют требованиям к объектам-последовательностям, включая любые новые классы, определёнными вами.

Т.к. join() – это строковой метод, то он может работать как со строками в UNICODE, так и с простыми строками в ASCII. Если бы join() был бы методом последовательности, то последовательность должна была бы решать на основе типа строки-разделителя, какой тип строки использовать.

Если ни один из этих аргументов вас не убедил, то вы можете продолжать использовать функцию join() из модуля string:
Код

string.join(['1', '2', '4', '8', '16'], ", ")




--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
srd
Дата 1.11.2005, 08:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


Профиль
Группа: Участник Клуба
Сообщений: 951
Регистрация: 30.8.2003
Где: Владивосток

Репутация: 7
Всего: 49



1.4.8. Как быстры исключения?

Сам по себе блок try/except очень эффективен. Но обработка исключения обходится дорого. В версиях Питона младше 2.0 часто использовалась следующая идиома:
Код

try:
    value = dict[key]
except KeyError:
    dict[key] = getvalue(key)
    value = dict[key]

Это имело смысл только в том случае, если dict почти всегда содержал нужный ключ. В противном случае вы писали бы что-то вроде:
Код

if dict.has_key(key):
    value = dict[key]
else:
    dict[key] = getvalue(key)
    value = dict[key]

(В Питоне 2.0 и выше вы можете написать value = dict.setdefault(key, getvalue(key)).)

1.4.9. Почему в Питоне нет инструкции switch или case?

Вы достаточно легко можете обойтись последовательностью if… elif… elif… else. Существует несколько предложений по поводу синтаксиса инструкции switch, но пока нет согласия, где и как задавать диапазоны тестов. Обратитесь к документу PEP 275 (http://www.python.org/peps/pep-0275.html), что бы узнать текущий статус или получить подробности.
Если вам требуется осуществить выбор из очень большого количества вариантов, вы vожете создать словарь, проецирующий варианты в вызовы функций. Например:
Код

def function_1 (...):
    ...

functions = {'a': function_1,
             'b': function_2, 
             'c': self.method_1, ...}

func = functions[value]
func()

Кроме того, для вызова методов объекта, вы можете воспользоваться встроенной функцией getattr() для получения метода по его имени.
Код

def visit_a (self, ...):
    ...
...

def dispatch (self, value):
    method_name = 'visit_' + str(value)
    method = getattr(self, method_name)
    method()

Здесь предполагается, что вы для именования методов используете некоторый префикс, например visit_, как в примере. Без префикса, если значения аргументов приходят из сомнительного источника, атакующий получает возможность вызвать любой метод вашего объекта.

1.4.10. Не лучше было бы эмулировать потоки в интерпретаторе, а не надеяться на реализацию потоков, зависящую от операционной системы?

Ответ 1: К сожалению, интерпретатор проталкивает по крайней мере один кадр стека Си для каждого кадра стека Питона. Кроме того, исключения могут обратно вызвать Питон практически в произвольный момент времени. Поэтому полная реализация многопоточности требует поддержки со стороны Си.
Ответ 2: К счастью, существует Stackless Python (http://www.stackless.com/), представляющий из себя полностью перепроектированный цикл интерпретатора, не затрагивающий стека Си. Он всё ещё экспериментальный, но выглядит очень многообещающе. Хотя существует бинарная совместимость со стандартным Питоном, пока неясно, станет ли Stackless частью ядра – возможно, это слишком революционно.

1.4.11 Почему лямбда-форма не может содержать инструкции?

В Питоне лямбда-формы не могут содержать инструкции, потому что в Питоне синтаксический фреймворк не может управляться с инструкциями, вложенными в выражения. Однако это не такая уж серьёзная проблема. В отличие от лямбды в других языках программирования, лямбда в Питоне – это только короткая форма записи для случая, когда вам лень определить функцию.
В Питоне функции всегда являются объектами первого класса, и могут быть объявлены в локальной области действия. Единственное преимущество использования лямбды вместо объявленной локально функции, это то, что вам не требуется вводить имя для функции – но ведь это просто локальная переменная, которой присвоен объект-функция, имеющий тот же тип, что и лямбда.

Это сообщение отредактировал(а) srd - 1.11.2005, 09:36


--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
srd
Дата 4.11.2005, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


Профиль
Группа: Участник Клуба
Сообщений: 951
Регистрация: 30.8.2003
Где: Владивосток

Репутация: 7
Всего: 49



1.4.12. Можно ли скомпилировать в машинный код, Си или любой другой язык программу на Питоне?

Не всё так просто. Высокоуровневые типы данных, динамическая типизация объектов и вызовы интерпретатора (с помощью eval() или exec()) во время исполнения – всё это вместе приводит к тому, что «скомпилированная» программа на Питоне будет состоять в основном из вызовов питоновской библиотеки времени выполнения, даже для выглядящих простыми операций вида x+1.

Существует несколько проектов, обсуждавшихся в питоновской группе новостей и на прошедших конференциях, посвящённых Питону, которые показали, что подобная реализация возможна, но увеличение (например, двукратное) скорости выполнения очень незначительно. Jython использует похожий принцип для компиляции в байт-код Java. (Jim Hugunin продемонстрировал это совместно с анализом всей программы, тысячекратное увеличение скорости достижимо для маленьких демонстрационных программ. За подробностями обратитесь к протоколам конференции по Питону 1997 года).

Исходный код на Питоне всегда транслируется в байт-код, и этот байт-код исполняется питоновской виртуальной машиной. Для того, чтобы избежать накладных расходов при повторяющемся разборе и транслировании редко изменяющихся модулей, байт-код записывается в файл с расширением «.pyc». Если соответствующий файл «.py» был изменён, то он снова разбирается и транслируется, а «.pyc» файл перезаписывается.

Здесь нет никой разницы в производительности, т.к. байт-код, прочитанный из «.pyc» файла, точно такой же, как полученный путём прямой трансляции. Единственная разница в том, что загрузка кода из «.pyc» файла выполняется быстрее, чем разбор и трансляция «.py» файла. Таким образом, существование «.pyc» файла уменьшает время запуска скриптов на Питоне. Вы можете использовать модуль Lib/compileall.py для того, чтобы создать соответствующие «.pyc» файлы для данного набора модулей.

Обратите внимание, что главный скрипт, исполняемый Питоном, даже если его файл имеет расширение .py, не компилируется в «.pyc» файл. Он компилируется в байт-код, но этот байт-код не сохраняется в файл. Обычно главные скрипты довольно короткие, потому здесь нет потерь в скорости.

Существует несколько программ, которые облегчают смешивание кода на Питоне и Си для увеличения производительности. Например, Psyco, Pyrex, PyInline, Py2Cmod и Weave.

1.4.13. Как Питон управляет памятью?

Менеджер памяти в Питоне зависит от реализации. Стандартная реализация Питона на Си использует подсчёт ссылок для обнаружения недоступных объектов и другой механизм для сбора цикличных ссылок – периодически выполняется алгоритм поиска цикличных ссылок и все обнаруженные недоступные объекты удаляются. Модуль gc предоставляет функции для сбора мусора, получения отладочной статистики и настройки параметров сборщика мусора.

Jython полагается на среду времени выполнения Java и использует сборщик мусора из JVM. Эта особенность может привести к некоторым проблемам при портировании кода, зависящего от реализации с подсчётом ссылок.

Иногда объекты временно попадают в traceback, и не разрушаются тогда, когда вы могли этого ожидать. Для очистки traceback выполните такой код:
Код

import sys
sys.exc_clear()
sys.exc_traceback = sys.last_traceback = None

Traceback используется для отчётов об ошибках, реализации отладчиков и т.п. Он может содержать кусок состояния программы, полученный во время обработки исключения (обычно, самого последнего исключения).

Если нет ни цикличных ссылок, ни tracebacks, то программа не нуждается в явном управлении памятью.

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

Традиционный сборщик мусора также становится проблемой, если Питон встраивается в другие приложения. Пока Питон работает сам по себе, можно свободно заменить стандартные вызовы malloc() и free() версиями, предоставляемыми библиотекой сборщика мусора. Но приложение с интегрированным Питоном может иметь собственную замену для malloc() и free(). Сейчас Питон работает со всем, что имеет правильную реализацию malloc() и free().

В Jython следующий код (который прекрасно работает в CPython) приведёт к нехватке файловых дескрипторов до того, как случится нехватка памяти:
Код

for file in <very long list of files>:
    f = open(file)
    c = f.read(1)

Если используется стратегия с подсчётом ссылок и деструкторами, каждое новое присваивание f закрывает предыдущий файл. Если используется сборщик мусора, то это не гарантируется. Если вы хотите писать код, который будет работать с любой реализацией Питона, вы должны явно закрыть файл.
Код

for file in <very long list of files>:
    f = open(file)
    c = f.read(1)
    f.close()




--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
setq
Дата 10.11.2005, 14:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 707
Регистрация: 28.9.2003

Репутация: 19
Всего: 26



1.1.1 Существует ли для Питона отладчик кода с точками останова, пошаговым выполнением и т.д?

Да.

Модуль pdb -- простой, но отвечающий большинству требований консольный отладчик для Питона. Он является частью стандартной библиотеки и описан в руководстве. Вы можете самостоятельно написать свой собственный отладчик, используя код pdb в качестве примера.

Интерактивная среда разработки IDLE, являющаяся частью стандартной поставки языка Питон (обычно доступная как Tools/scripts/idle (*)), включает графический отладчик. Документация по отладчику IDLE доступна по адресу http://www.python.org/idle/doc/idle2.html#Debugger .

Другая IDE для Питона - PythonWin - включает в себя GUI отладчик на базе pdb. PythonWin подсвечивает точки останова а также имеет несколько cool features such as debugging non-Pythonwin programs. Описание можно найти здесь: http://www.python.org/windows/pythonwin/ . Последние версии PythonWin доступны как часть поставки ActivePython (http://www.activestate.com/Products/ActivePython/index.html).

Boa Constructor - это IDE и среда для разработки GUI приложений, использующая wxPython. It offers visual frame creation and manipulation, an object inspector, many views on the source like object browsers, inheritance hierarchies, doc string generated html documentation, an advanced debugger, integrated help, and Zope support.

Eric3 - среда разработки построенная на PyQt и Scintilla editing component.

Pydb -- версия стандартного питоновского отладчика pdb, модифицированного под использование с DDD (Data Display Debugger) - популярного графического интерфейса для отладчиков (debugger front end). Pydb можно найти здесь: http://packages.debian.org/unstable/devel/pydb.html . DDD можно найти здесь: http://www.gnu.org/software/ddd .

Существует несколько коммерческих IDE для Питона, в которых есть графические отладчики. Например:
Wing IDE (http://wingide.com)
Komodo IDE (http://www.activestate.com/Products/Komodo)


(*) "обычно доступная как Tools/scripts/idle" -- у меня под WindowsXP в этой папке нет такого файла.
PM MAIL   Вверх
setq
Дата 11.11.2005, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 707
Регистрация: 28.9.2003

Репутация: 19
Всего: 26



из Programming FAQ

1.1.2 Есть ли инструменты, помогающие находить баги и проводить статический анализ?

Да.

PyChecker - это инструмент статического анализа, который находит ошибки в исходном коде а также проверяет стиль и сложность программ (code complexity). Вы можете загрузить PyChecker с http://pychecker.sf.net .

Pylint - другая утилита, проверяющая отвечает ли модуль стандартам написания кода и позволяющая писать собственные plug-in'ы. Кроме проверки на наличие ошибок, которую выполняет PyChecker, Pylint имеет несколько дополнительных возможностей, таких как проверка длины строк, проверка того отвечают ли переменные формату именования, установленному Вашим стандартом кодирования, а также реализованы ли все объявленные интерфейсы, и прочее. http://www.logilab.org/projects/pylint/documentation описывает полный список возможностей Pylint.

1.1.3 Как создать самостоятельную программу (stand-alone binary) из скрипта на Питоне?

Вам не обязательно компилировать код на Питоне в Си, если всё что Вы хотите это получить самостоятельную программу, которую пользователи могли бы загружать и исполнять без установленного интерпретатора Питона. Есть несколько утилит, которые определяют какие модули использует Ваша программа и связывают их с бинарниками Питона, создавая один исполняемый файл.

Во-первых, это утилита freeze из каталога исходников Питона (Tools/freeze). Она конвертирует питоновский байт-код в C arrays; a C compiler you can embed all your modules into a new program, which is then linked with the standard Python modules. (*)

Ваш код сканируется по рекурсивному алгоритму в поисках инструкций импорта (в обоих формах) и соответствующие модули ищутся в стандартных путях Питона или в директории исходников (для встроенных модулей). Затем модули, содержащие питоновский байт-код, переводятся в Си (array initializers, из которых можно восстановить code-объекты с помощью модуля marshal) (**) и создаётся custom-made конфигурационный файл, который содержит только те встроенные модули, которые используются Вашей программой. Затем сгенерированный код Си компилируется и линкуется с питоновским интерпретатором, образуя self-contained binary, делающий то же самое, что и Ваш скрипт.

Очевидно, для утилиты freeze нужен компилятор Си. Существуют другие инструменты, которые его не требуют. Первый - Gordon McMillan's installer по адресу

http://www.mcmillan-inc.com/install1.html (***)

который работает под Windows, Linux и по крайней мере на нескольких Unix'ах.

Другой - Thomas Heller's py2exe (только под Windows) по адресу

http://starship.python.net/crew/theller/py2exe

Третий - Christian Tismer's SQFREEZE, дописывающий байт-код в "специально приготовленный" питоновский интерпретатор, умеющий находить этот байт-код в своём исполняемом файле. Возможно подобный подход будет реализован в версии 2.4, due out some time in 2004.

Среди прочих стоит упомянуть Fredrik Lundh's Squeeze (****) и Anthony Tuininga's cx_Freeze.

---
кстати, тема уже обсуждалась у нас на форуме и вроде бы продуктивно: читать


1.1.4 Есть ли стандарт или единый стиль для написания кода в Питоне?

Да. Стиль кодирования, который соблюдается при написании модулей стандартной библиотеки описан как PEP 8.


(*) ниасилил
(***) сдох?
(****) "The Squeeze utility is no longer available"


(**) откровенно говоря, не понимаю, зачем переводить скомпилированный питоновский байт-код в Си, если и так интерпретатор зашивается внутрь executable. если кто-то в курсе, как всё это работает - прокомментируйте.

ответ Void:
Если я правильно понял, то речь идет всего лишь о способе записи байт-кода непосредственно в исходниках Си, допустим есть у меня объект:

Код

>>> x = 2
>>> marshal.dumps(x)
'i\x02\x00\x00\x00'


freeze его превратит во что-то вроде:

Код

char obj_d[] = {'i', 2, 0, 0};


Вероятно, это сделано, чтобы переложить все заботы о генерации исполняемого файла на плечи компилятора Си.

Это сообщение отредактировал(а) setq - 11.11.2005, 19:05
PM MAIL   Вверх
srd
Дата 19.3.2006, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Нереварин
**


Профиль
Группа: Участник Клуба
Сообщений: 951
Регистрация: 30.8.2003
Где: Владивосток

Репутация: 7
Всего: 49



1.1 Общие вопросы о GUI
1.1.1 Какие независимые от платформы инструментарии GUI доступны в Питоне?
Это зависит от того, на какие платформы вы ориентируетесь. Есть несколько.
1.1.1.1 Tkinter
Стандартные сборки Питона включают объектно-ориентированный интерфейс к библиотеке виджетов Tcl/Tk, называющейся Tkinter. Эта библиотека, возможно, самая легкая в установке и использовании. За подробностями обратитесь к домашней странице Tcl/Tk (http://www.tcl.tk). Tcl/Tk полностью переносима на платформы MacOS, Windows и UNIX.
1.1.1.2 wxWindows
wxWindows – это написанная на Си++ переносимая библиотека классов для GUI, представляющая собой интерфейс для разнообразных библиотек, специфичных для платформы. wxWindows поддерживает Windows и MacOS. На UNIX поддерживается как GTK+, так и Motif. wxWindows сохраняет облик используемой графической библиотеки, содержит очень богатую коллекцию виджетов и классов GDI. Обратитесь к странице http://www.wxwindows.org/ за подробностями.
wxWidgets – это расширение, оборачивающее многие C++ - классы из wxWindows и быстро получившее популярность среди разработчиков на Питоне. Вы можете получить wxWidgets как часть дистрибутива wxWindows с исходными кодами или из CVS, или непосредственно с их домашней страницы.
1.1.1.3 Qt
Существуют связки для Qt (PyQt) или для KDE (PyKDE). Если вы пишете программное обеспечение с открытыми исходными кодами, то вам не надо платить за PyQt, но если вы хотите писать проприетарное программное обеспечение, то вы должны купить лицензию для PyQt у http://www.riverbankcomputing.co.uk/ и лицензию на Qt от http://www.trolltech.com.
1.1.1.4 GTk+
James Henstridge создал PyGTk, связку для библиотеки GTk+. Обратитесь к ftp://ftp.gtk.org/pub/gtk/python/.
1.1.1.5 FLTK
Связка Питона с библиотекой FLTK (http://www.fltk.org/), простой, но мощной и зрелой кросс-платформенной оконной системой, доступна благодаря проекту http://pyfltk.sourceforge.net.
1.1.1.6 FOX
Для библиотеки FOX (http://www.fox-toolkit.org/) существует обёртка, называемая FXpy (http://fxpy.sourceforge.net/). Поддерживаются как UNIX, так и Windows.
1.1.1.7 OpenGL
Связку для OpenGL можно найти на http://pyopengl.sourceforge.net.
1.1.2 Какие платформенно-специфичные инструментарии для GUI доступны в Питоне?
Порт для Mac (http://www.python.org/download/mac), созданный Jack Jansen, имеет богатый и продолжающий увеличиваться набор модулей для поддержки «родных» для Mac вызовов. Этот порт включает в себя поддержку библиотек Carbon для MacOS9 и MacOS X. После установки расширения PyObjc Objective-C bridge (http://pyobjc.sourceforge.net/) у программ на Питоне появляется возможность использовать библиотеки Cocoa. Обратитесь за подробностями к документации, поставляемой вместе с портом на Mac.
Pythonwin (http://www.python.org/doc/faq/windows/), созданный Mark Hammond, содержит интерфейс к MFC и среду программирования, использующую этот интерфейс и в основном написанную на Питоне.


--------------------
Не смей читать мою подпись!!!
PM MAIL Jabber   Вверх
Google
  Дата 26.6.2019, 02:41 (ссылка)  





  Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Python: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1184 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.