Каковы менее известные, но полезные функции языка программирования Python?
.get
значение import this
__missing__
позиций .pth
файлы try/except/else
print()
with
оператор >>> x=[1,1,2,'a','a',3]
>>> y = [ _x for _x in x if not _x in locals()['_[1]'] ]
>>> y
[1, 2, 'a', 3]
"местные жители () [' _ [1]']" "секретное название" создаваемого списка. Очень полезный, когда состояние списка, создаваемого влияние последующие решения сборки.
spam
модуль в стандартном Python Это используется для тестирования.
я выбрал его от ctypes
учебное руководство . Попробуйте его сами:
>>> import __hello__
Hello world...
>>> type(__hello__)
<type 'module'>
>>> from __phello__ import spam
Hello world...
Hello world...
>>> type(spam)
<type 'module'>
>>> help(spam)
Help on module __phello__.spam in __phello__:
NAME
__phello__.spam
FILE
c:\python26\<frozen>
ctypes
учебное руководство starship.python.net/crew/theller/ctypes/…
– jfs
22.07.2009, 09:27
элементы Словаря Доступа как атрибуты (свойства). таким образом, если a1=AttrDict () имеет ключевое 'имя'-> вместо a1 ['имя'] мы можем легко получить доступ к атрибуту имени использования a1-> <час> a1.name
class AttrDict(dict):
def __getattr__(self, name):
if name in self:
return self[name]
raise AttributeError('%s not found' % name)
def __setattr__(self, name, value):
self[name] = value
def __delattr__(self, name):
del self[name]
person = AttrDict({'name': 'John Doe', 'age': 66})
print person['name']
print person.name
person.name = 'Frodo G'
print person.name
del person.age
print person
Все динамично
"Нет никакого времени компиляции". Все в Python - время выполнения. Модуль 'определяется' путем выполнения источника модуля, от начала до конца, точно так же, как сценарий, и получающееся пространство имен является пространством атрибута модуля. Аналогично, класс 'определяется' путем выполнения тела класса, от начала до конца, и получающееся пространство имен является пространством атрибута класса. Тело класса может содержать абсолютно произвольный код - включая операторов импорта, циклы и другие операторы класса. При создании класса функционируйте или даже модуль 'динамично', относительно как иногда просят, не твердо; на самом деле невозможно избежать, так как все 'динамично'.
dict.x = 3
, и Python won' t позволяют Вам),
– Denilson Sá Maia
21.08.2010, 10:56
dict.x = 3
не имеет никакого отношения к вещам, являющимся динамичным, но с dict
тип, не позволяющий атрибуты быть присвоенными. Можно сделать собственные классы, в Python, это don' t позволяют это. Можно сделать собственный тип в C, который действительно позволяет его. It' s не связанный.
– Thomas Wouters
10.09.2010, 11:33
Моделирование третичного использования оператора и и или.
и и или операторы в Python возвращают сами объекты, а не булевские переменные. Таким образом:
In [18]: a = True
In [19]: a and 3 or 4
Out[19]: 3
In [20]: a = False
In [21]: a and 3 or 4
Out[21]: 4
Однако Py 2.5, кажется, добавил явный третичный оператор
In [22]: a = 5 if True else '6'
In [23]: a
Out[23]: 5
ну, это работает, если Вы уверены, что Ваш истинный пункт не оценивает ко Лжи. пример:
>>> def foo():
... print "foo"
... return 0
...
>>> def bar():
... print "bar"
... return 1
...
>>> 1 and foo() or bar()
foo
bar
1
Для разбираний в нем Вы имеете только к немного больше:
>>> (1 and [foo()] or [bar()])[0]
foo
0
Однако это не столь симпатично. если Ваша версия Python поддерживает его, используйте условный оператор.
>>> foo() if True or bar()
foo
0
(falseValue, trueValue)[cond]
инструмент для очистки (IMO) способ моделировать тернарный оператор.
– Ponkadoodle
16.05.2010, 21:09
Объекты в булевом контексте
Пустые кортежи, списки, dicts, строки и много других объектов эквивалентны Лжи в булевом контексте (и непустой эквивалентны Истинному).
empty_tuple = ()
empty_list = []
empty_dict = {}
empty_string = ''
empty_set = set()
if empty_tuple or empty_list or empty_dict or empty_string or empty_set:
print 'Never happens!'
Это позволяет логическим операциям возвращать один из, его - операнды вместо Истинного/ложного, который полезен в некоторых ситуациях:
s = t or "Default value" # s will be assigned "Default value"
# if t is false/empty/none
существует общая идиома в Python обозначения методов и других участников класса, которые не предназначаются, чтобы быть частью внешнего API класса путем давания им имен, которые запускаются с подчеркиваний. Это удобно и работает очень хорошо на практике, но это производит ложное впечатление, что Python не поддерживает истинную инкапсуляцию частного кода и/или данных. На самом деле Python автоматически дает Вам лексические закрытия , которые делают очень легким инкапсулировать данные намного большим количеством пуленепробиваемого способа, когда ситуация действительно гарантирует его. Вот изобретенный пример класса, который использует эту технику:
class MyClass(object):
def __init__(self):
privateData = {}
self.publicData = 123
def privateMethod(k):
print privateData[k] + self.publicData
def privilegedMethod():
privateData['foo'] = "hello "
privateMethod('foo')
self.privilegedMethod = privilegedMethod
def publicMethod(self):
print self.publicData
И вот изобретенный пример его использования:
>>> obj = MyClass()
>>> obj.publicMethod()
123
>>> obj.publicData = 'World'
>>> obj.publicMethod()
World
>>> obj.privilegedMethod()
hello World
>>> obj.privateMethod()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'privateMethod'
>>> obj.privateData
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'MyClass' object has no attribute 'privateData'
ключ - то, что privateMethod
и privateData
не действительно атрибуты obj вообще, таким образом, к ним нельзя получить доступ снаружи, и при этом они не обнаруживаются в dir()
или подобный. Они - локальные переменные в конструкторе, абсолютно недоступном за пределами __init__
. Однако из-за волшебства закрытий, они действительно на переменные экземпляра с тем же временем жизни как объект, с которым они связаны, даже при том, что нет никакого способа получить доступ к ним снаружи кроме (в этом примере) путем вызова privilegedMethod
. Часто этот вид очень строгой инкапсуляции является излишеством, но иногда это действительно может быть очень удобно для хранения API или пространства имен, писклявого чистый.
В Python 2.x, единственный способ иметь изменяемое частное состояние с изменяемым объектом (таким как dict в этом примере). Многие люди отметили относительно того, насколько раздражающий это может быть. Python 3.x удалит это ограничение путем представления nonlocal
ключевое слово, описанное в PEP 3104.
__getattribute__
или __getattr__
сигнальная метка и направляют принятые вызовы соответственно. Снова, тайна и Python не являются хорошей идеей.
– Jeffrey Jose
28.05.2010, 09:35
Если Вы используете exec
в функции, переменные правила поиска изменяются решительно. Закрытия больше не возможны, но Python позволяет произвольные идентификаторы в функции. Это дает Вам "модифицируемых местных жителей ()" и может привыкнуть к идентификаторам звездообразного импорта. На оборотной стороне это делает каждый поиск медленнее, потому что переменные заканчиваются в dict, а не слотах в кадре:
>>> def f():
... exec "a = 42"
... return a
...
>>> def g():
... a = 42
... return a
...
>>> import dis
>>> dis.dis(f)
2 0 LOAD_CONST 1 ('a = 42')
3 LOAD_CONST 0 (None)
6 DUP_TOP
7 EXEC_STMT
3 8 LOAD_NAME 0 (a)
11 RETURN_VALUE
>>> dis.dis(g)
2 0 LOAD_CONST 1 (42)
3 STORE_FAST 0 (a)
3 6 LOAD_FAST 0 (a)
9 RETURN_VALUE
Функциональная поддержка.
Генераторы и выражения генератора, конкретно.
Ruby сделал эту господствующую тенденцию снова, но Python может сделать это точно также. Не столь повсеместный в библиотеках как в Ruby, который слишком плох, но мне нравится синтаксис лучше, это более просто.
, поскольку они не так повсеместны, я не вижу как много примеров там на том, почему они полезны, но они позволили мне писать инструменту для очистки, более эффективному коду.
config.AppSettings["somekey"]
(или config.AppSettings.Settings[]
) без ошибок права доступа?
– Brent Faust
13.10.2019, 14:39
Можно создать словарь от ряда длины 2 последовательности. Чрезвычайно удобный, когда у Вас есть список значений и список массивов.
>>> dict([ ('foo','bar'),('a',1),('b',2) ])
{'a': 1, 'b': 2, 'foo': 'bar'}
>>> names = ['Bob', 'Marie', 'Alice']
>>> ages = [23, 27, 36]
>>> dict(zip(names, ages))
{'Alice': 36, 'Bob': 23, 'Marie': 27}
dict((x, x**2) for x in range(10))
.
– Marian
30.05.2010, 01:57
__slots__
хороший способ сохранить память, но очень трудно получить dict значений объекта. Вообразите следующий объект:
class Point(object):
__slots__ = ('x', 'y')
Теперь, когда объект, очевидно, имеет два атрибута. Теперь мы можем создать экземпляр его и создать dict из него этот путь:
>>> p = Point()
>>> p.x = 3
>>> p.y = 5
>>> dict((k, getattr(p, k)) for k in p.__slots__)
{'y': 5, 'x': 3}
Это однако не будет работать, если точка была разделена на подклассы, и были добавлены новые слоты. Однако Python автоматически реализует __reduce_ex__
для помощи copy
модуль. Этим можно злоупотребить для получения dict значений:
>>> p.__reduce_ex__(2)[2][1]
{'y': 5, 'x': 3}
__reduce_ex__
может быть переопределено в подклассах, и с тех пор it' s также используемый для соления, это часто. (Если you' ре, делающее контейнеры данных, необходимо думать об использовании его также! или it' s младшие одноуровневые элементы __getstate__
и __setstate__
.)
– Ken Arnold
01.07.2010, 10:53
Присвоение и удаление частей:
>>> a = range(10)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[:5] = [42]
>>> a
[42, 5, 6, 7, 8, 9]
>>> a[:1] = range(5)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> del a[::2]
>>> a
[1, 3, 5, 7, 9]
>>> a[::2] = a[::-2]
>>> a
[9, 3, 5, 7, 1]
Примечание : при присвоении расширенным частям (s[start:stop:step]
), присвоенное повторяемое должно иметь ту же длину как часть.
Часть из встроенный избранное, карта (), уменьшает (), и фильтр (). Все чрезвычайно быстрые и мощные.
reduce()
– SingleNegationElimination
18.11.2009, 07:08
reduce()
может достигнуть всего, что можно сделать с map()
, filter()
, или перечислить понимания "
– Kragen Javier Sitaker
12.01.2012, 17:31
Генераторы
я думаю, что много начала разработчиков Python передает по генераторам, действительно не схватывая то, что они для или получение любого смысла их питания. Только когда я считал представление PyCon David M. Beazley генераторов (это доступно здесь ), что я понял, насколько полезный (важный, действительно) они. То представление осветило то, что было для меня совершенно новым способом запрограммировать, и я рекомендую его любому, у кого нет глубокого понимания генераторов.
Метаклассы
, конечно:-) , Что такое метакласс в Python?
Первоклассные функции
Это не действительно скрытая функция, но то, что функции являются объектами первого класса, является просто большим. Можно раздать их как любая другая переменная.
>>> def jim(phrase):
... return 'Jim says, "%s".' % phrase
>>> def say_something(person, phrase):
... print person(phrase)
>>> say_something(jim, 'hey guys')
'Jim says, "hey guys".'
Неявная конкатенация:
>>> print "Hello " "World"
Hello World
Полезный, когда Вы хотите сделать соответствие длинного текста на нескольких строках в сценарии:
hello = "Greaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Hello " \
"Word"
или
hello = ("Greaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Hello "
"Word")
Используя аргументы ключевого слова как присвоения
Иногда каждый хочет создать диапазон из функций в зависимости от одного или нескольких параметров. Однако это могло бы легко привести к закрытиям все обращение к тому же объекту и значению:
funcs = []
for k in range(10):
funcs.append( lambda: k)
>>> funcs[0]()
9
>>> funcs[7]()
9
Этого поведения можно избежать путем превращения лямбда-выражения в функцию, зависящую только от ее аргументов. Ключевой параметр хранит текущее значение, которое связывается с ним. Вызов функции не должен быть изменен:
funcs = []
for k in range(10):
funcs.append( lambda k = k: k)
>>> funcs[0]()
0
>>> funcs[7]()
7
def make_lambda(k): return lambda: k
.
– Jason Orendorff
29.01.2010, 09:03
"lambda: k=k:k"
и сразу поймете, что это - " saving" текущее значение " k" (поскольку лямбда создается), и присоединение его к самой лямбде. Это работает то же с нормальным " def" функции, также.
– Nick Perkins
21.09.2011, 10:34
Тернарный оператор
>>> 'ham' if True else 'spam'
'ham'
>>> 'ham' if False else 'spam'
'spam'
Это было добавлено в 2,5, до которого Вы могли использовать:
>>> True and 'ham' or 'spam'
'ham'
>>> False and 'ham' or 'spam'
'spam'
Однако, если бы значения Вы хотите работать с, считался бы ложью, существует различие:
>>> [] if True else 'spam'
[]
>>> True and [] or 'spam'
'spam'
>>> x = 5
>>> 1 < x < 10
True
>>> 10 < x < 20
False
>>> x < 10 < x*10 < 100
True
>>> 10 > x <= 9
True
>>> 5 == x > 4
True
В случае, если Вы думаете, что это делает 1 < x
, который выходит как True
, и затем сравнение True < 10
, который является также True
, тогда не, это действительно не, что происходит (см. последний пример.) Это действительно переводит в 1 < x and x < 10
, и x < 10 and 10 < x * 10 and x*10 < 100
, но с меньшим количеством ввода и каждым термином только оценен однажды.
(< 1 x 10)
. Можно даже применить их к отдельным аргументам, как (= 10)
: cs.cmu.edu/Groups/AI/html/hyperspec/HyperSpec/Body/…
– Ken
27.05.2010, 10:31
Вложенные понимания списка и выражения генератора:
[(i,j) for i in range(3) for j in range(i) ]
((i,j) for i in range(4) for j in range(i) )
Они могут заменить огромные блоки кода вложенного цикла.
for
операторы состоит в том, чтобы быть записан в порядке you' d ожидают, что они будут записаны в стандарте для цикла с внешней стороны внутрь.
– sykora
26.01.2010, 23:17
for
с и if
с с yield x
внутренняя часть. Для преобразования этого в выражение генератора переместите x
первый, удалите все двоеточия (и yield
) и окружите все это в круглых скобках. Для создания понимания списка вместо этого, замените внешний parens квадратными скобками.
– Ken Arnold
14.06.2011, 15:30
Оператор, перегружающийся для set
встроенный:
>>> a = set([1,2,3,4])
>>> b = set([3,4,5,6])
>>> a | b # Union
{1, 2, 3, 4, 5, 6}
>>> a & b # Intersection
{3, 4}
>>> a < b # Subset
False
>>> a - b # Difference
{1, 2}
>>> a ^ b # Symmetric Difference
{1, 2, 5, 6}
[еще 114] деталь из стандартного справочного руководства по библиотеке: Типы Набора
Интерактивное заполнение клавишей Tab Интерпретатора
try:
import readline
except ImportError:
print "Unable to load readline module."
else:
import rlcompleter
readline.parse_and_bind("tab: complete")
>>> class myclass:
... def function(self):
... print "my function"
...
>>> class_instance = myclass()
>>> class_instance.<TAB>
class_instance.__class__ class_instance.__module__
class_instance.__doc__ class_instance.function
>>> class_instance.f<TAB>unction()
необходимо будет также установить переменную среды PYTHONSTARTUP.
easy_install ipdb
- тогда можно использовать import ipdb; ipdb.set_trace()
– Doug Harris
21.05.2010, 12:03
readline.parse_and_bind ("bind ^I rl_complete")
– Foo Bah
11.02.2011, 03:20
Основные сообщения:)
import this
# btw look at this module's source :)
<час> Дзэн Python, Tim Peters
Красивый лучше, чем ужасный.
Явный лучше, чем неявный.
Простой лучше, чем комплекс.
Комплекс лучше, чем сложный.
Плоский лучше, чем вложенный.
Редкий лучше, чем плотный.
количества Удобочитаемости.
Особые случаи не являются достаточно особенными для нарушения правил.
, Хотя практичность бьет чистоту.
Ошибки никогда не должны передавать тихо.
, Если явно не заставлено замолчать.
Перед лицом неоднозначности, откажитесь от искушения предположить. Должны быть один - и предпочтительно только один - очевидный способ сделать это.
, Хотя тот путь не может быть очевидным сначала, если Вы не голландцы.
Теперь лучше, чем никогда.
, Хотя никогда не часто лучше, чем [1 120] право теперь.
, Если реализацию трудно объяснить, это - плохая идея.
, Если реализацию легко объяснить, это может быть хорошая идея.
Пространства имен являются одной гудящей прекрасной идеей - давайте сделаем больше из тех!
print s.translate("".join(chr(64<i<91 and 65+(i-52)%26 or 96<i<123 and 97+(i-84)%26 or i) for i in range(256)))
, и это выглядит намного лучше теперь!!:-D
– fortran
26.06.2009, 03:12
Переповышение исключений :
# Python 2 syntax
try:
some_operation()
except SomeError, e:
if is_fatal(e):
raise
handle_nonfatal(e)
# Python 3 syntax
try:
some_operation()
except SomeError as e:
if is_fatal(e):
raise
handle_nonfatal(e)
оператор 'повышения' без аргументов в обработчике ошибок говорит Python повторно повышать исключение с оригиналом, traceback неповрежденный , позволяя Вам сказать, "о, извините, извините, я не означал ловить, это, извините, извините".
, Если Вы хотите распечатать, сохраните или играйте с исходным traceback, можно получить его с sys.exc_info (), и печать его как Python была бы делаться с 'traceback' модулем.
raise e
вместо этого, который doesn' t сохраняют исходный traceback.
– habnabit
27.01.2009, 15:14
exc_info = sys.exc_info(); raise exc_info[0], exc_info[1], exc_info[2]
эквивалентно этому, но можно менять те значения (например, изменить тип исключительной ситуации или сообщение),
– ianb
06.05.2009, 10:27
Для добавления большего количества модулей Python (espcially сторонние) большинство людей, кажется, использует переменные среды PYTHONPATH, или они добавляют символьные ссылки или каталоги в их каталогах пакетов сайта. Иначе, должен использовать *.pth файлы. Вот официальное объяснение документа Python:
"Наиболее удобный способ [для изменения пути поиска Python] состоит в том, чтобы добавить конфигурационный файл пути к каталогу, это уже находится на пути Python, обычно к.../site-packages/каталог. Конфигурационные файлы пути имеют расширение .pth, и каждая строка должна содержать единственный путь, который будет добавлен к sys.path. (Поскольку новые пути добавляются к sys.path, модули в добавленных каталогах не переопределят стандартные модули. Это означает, что Вы не можете использовать этот механизм для установки исправленных версий стандартных модулей.)"
проход () может взять вызываемый аргумент
, Например:
def seek_next_line(f):
for c in iter(lambda: f.read(1),'\n'):
pass
Эти iter(callable, until_value)
функция неоднократно называет callable
и приводит к своему результату, пока until_value
не возвращается.
lambda
ключевое слово необходимо здесь?
– SiegeX
13.08.2011, 10:29
объекты генераторов Создания
, Если Вы пишете
x=(n for n in foo if bar(n))
, можно вынуть генератор и присвоить его x. Теперь это означает, что можно сделать
for n in x:
, преимущество этого состоит в том, что Вам не нужно промежуточное устройство хранения данных, в котором Вы нуждались бы, если бы Вы сделали
x = [n for n in foo if bar(n)]
В некоторых случаях, это может привести к значительной скорости.
можно добавить многих если операторы до конца генератора, в основном копируя вложенный для циклов:
>>> n = ((a,b) for a in range(0,2) for b in range(4,6))
>>> for i in n:
... print i
(0, 4)
(0, 5)
(1, 4)
(1, 5)
Быть осторожными с изменяемыми параметрами по умолчанию
>>> def foo(x=[]):
... x.append(1)
... print x
...
>>> foo()
[1]
>>> foo()
[1, 1]
>>> foo()
[1, 1, 1]
Вместо этого необходимо использовать значение сигнальной метки, обозначающее "не данный" и замена изменяемым, которое Вы хотели бы как значение по умолчанию:
>>> def foo(x=None):
... if x is None:
... x = []
... x.append(1)
... print x
>>> foo()
[1]
>>> foo()
[1]
foo.func_defaults
. Который, будучи кортежем, неизменно.
– Robert Rossney
06.11.2009, 08:43
Передающие значения в функции генератора . Например, наличие этой функции:
def mygen():
"""Yield 5 until something else is passed back via send()"""
a = 5
while True:
f = (yield a) #yield a and possibly get f in return
if f is not None:
a = f #store the new value
Вы можете:
>>> g = mygen()
>>> g.next()
5
>>> g.next()
5
>>> g.send(7) #we send this back to the generator
7
>>> g.next() #now it will yield 7 until we send something else
7