Скрытые возможности Python [закрыто]

Поскольку язык программирования Go не поддерживает в настоящее время общие типы, это будет трудно сделать.

Почему у Go нет общих типов?

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

Дженерики удобны, но они сложны по сложности в системе типов и времени выполнения. Мы еще не нашли дизайн, который дает ценность, пропорциональную сложности, хотя мы продолжаем думать об этом. Между тем, встроенные карты и фрагменты Go, а также возможность использования пустого интерфейса для создания контейнеров (с явным распаковкой) означают, что во многих случаях можно написать код, который будет делать какие дженерики будут разрешены, если будет менее плавным.

Это остается открытой проблемой.

blockquote>

Посмотрите на пакет сортировки Go , чтобы увидеть, как он обрабатывает сравнения и другие операции, относящиеся к типу, путем определения sort.Interface с методами Len, Less и Swap.

1420
задан 30 revs, 24 users 18% 23 May 2017 в 12:34
поделиться

145 ответов

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>
2
ответ дан 2 revs 23 May 2017 в 22:34
поделиться

Создание словаря двух последовательностей, которые связали данные

In [15]: t1 = (1, 2, 3)

In [16]: t2 = (4, 5, 6)

In [17]: dict (zip(t1,t2))
Out[17]: {1: 4, 2: 5, 3: 6}
9
ответ дан 2 revs 23 May 2017 в 22:34
поделиться
  • 1
    +1 Для выделения малоизвестной техники. Очень хороший и благодарит развернуть мое знание. – Basic 2 May 2011 в 22:52

Объекты маленького intgers (-5.. 256) никогда создаваемый дважды:


>>> a1 = -5; b1 = 256
>>> a2 = -5; b2 = 256
>>> id(a1) == id(a2), id(b1) == id(b2)
(True, True)
>>>
>>> c1 = -6; d1 = 257
>>> c2 = -6; d2 = 257
>>> id(c1) == id(c2), id(d1) == id(d2)
(False, False)
>>>

Редактирование: Объекты списка никогда не уничтожали (только возражает в списках). Python имеет массив, в котором он поддерживает на высоком уровне к 80 пустым спискам. При уничтожении объекта списка - Python помещает его в тот массив и когда Вы создаете новый список - Python получает последний загнанный список от этого массива:


>>> a = [1,2,3]; a_id = id(a)
>>> b = [1,2,3]; b_id = id(b)
>>> del a; del b
>>> c = [1,2,3]; id(c) == b_id
True
>>> d = [1,2,3]; id(d) == a_id
True
>>>

6
ответ дан 2 revs 23 May 2017 в 22:34
поделиться
  • 1
    @user566930: Если Вы просто хотите отредактировать прокси, удалите все остальное. все элементы являются дополнительными в settings.xml – Sean Patrick Floyd 7 January 2011 в 16:39

ROT13 является допустимой кодировкой для исходного кода, если вы используете правильное объявление кодировки в верхней части файла кода:

#!/usr/bin/env python
# -*- coding: rot13 -*-

cevag "Uryyb fgnpxbiresybj!".rapbqr("rot13")
205
ответ дан 22 November 2019 в 20:19
поделиться

re могут вызывать функции!

Тот факт, что вы можете вызывать функцию каждый раз, когда что-то соответствует регулярному выражению, очень удобен. Здесь у меня есть пример замены каждого «Hello» на «Hi» и «there» на «Fred» и т. Д.

import re

def Main(haystack):
  # List of from replacements, can be a regex
  finds = ('Hello', 'there', 'Bob')
  replaces = ('Hi,', 'Fred,', 'how are you?')

  def ReplaceFunction(matchobj):
    for found, rep in zip(matchobj.groups(), replaces):
      if found != None:
        return rep

    # log error
    return matchobj.group(0)

  named_groups = [ '(%s)' % find for find in finds ]
  ret = re.sub('|'.join(named_groups), ReplaceFunction, haystack)
  print ret

if __name__ == '__main__':
  str = 'Hello there Bob'
  Main(str)
  # Prints 'Hi, Fred, how are you?'
72
ответ дан 22 November 2019 в 20:19
поделиться

Синтаксис распаковки был обновлен в последней версии, как показано в примере.

>>> a, *b = range(5)
>>> a, b
(0, [1, 2, 3, 4])
>>> *a, b = range(5)
>>> a, b
([0, 1, 2, 3], 4)
>>> a, *b, c = range(5)
>>> a, b, c
(0, [1, 2, 3], 4)
25
ответ дан 22 November 2019 в 20:19
поделиться

Умножение на логическое значение

Одна вещь, которую я постоянно делаю в веб-разработке, - это дополнительная печать параметров HTML. Мы все видели такой код на других языках:

class='<% isSelected ? "selected" : "" %>'

В Python вы можете умножать на логическое значение, и он делает именно то, что вы ожидаете:

class='<% "selected" * isSelected %>'

Это потому, что умножение переводит логическое значение в целое число (0 для False, 1 для True), а в python умножение строки на int повторяет строку N раз.

81
ответ дан 22 November 2019 в 20:19
поделиться

Этот ответ был перемещен в сам вопрос по просьбе многих людей.

63
ответ дан 22 November 2019 в 20:19
поделиться

Многострочные строки

Один из подходов - использовать обратную косую черту:

>>> sql = "select * from some_table \
where id > 10"
>>> print sql
select * from some_table where id > 10

Другой - использовать тройные кавычки:

>>> sql = """select * from some_table 
where id > 10"""
>>> print sql
select * from some_table where id > 10

Проблема с ними в том, что они не имеют отступа (плохо выглядят в вашем коде). Если вы попытаетесь сделать отступ, он просто напечатает введенные вами пробелы.

Третье решение, которое я нашел недавно, - разделить строку на строки и заключить их в круглые скобки:

>>> sql = ("select * from some_table " # <-- no comma, whitespace at end
           "where id > 10 "
           "order by name") 
>>> print sql
select * from some_table where id > 10 order by name

обратите внимание, что между строками нет запятой (это не кортеж), и вы должны учитывать любые конечные / ведущие пробелы, которые должна иметь ваша строка. Между прочим, все они работают с заполнителями (например, «меня зовут% s»% name ).

67
ответ дан 22 November 2019 в 20:19
поделиться

pow() также может эффективно вычислять (x ** y) % z.

Существует менее известный третий аргумент встроенной функции pow(), который позволяет вычислять xy по модулю z более эффективно, чем простое выполнение (x ** y) % z:

>>> x, y, z = 1234567890, 2345678901, 17
>>> pow(x, y, z)            # almost instantaneous
6

Для сравнения, (x ** y) % z для тех же значений не дал результата за одну минуту на моей машине.

56
ответ дан 22 November 2019 в 20:19
поделиться

Мне лично нравятся 3 разных кавычки

str = "I'm a string 'but still I can use quotes' inside myself!"
str = """ For some messy multi line strings.
Such as
<html>
<head> ... </head>"""

Также круто: не нужно избегать регулярных выражений, избежать ужасного обратного слэша с помощью необработанных строк :

str2 = r"\n" 
print str2
>> \n
24
ответ дан 22 November 2019 в 20:19
поделиться

Одно слово: IPython

Самоанализ вкладки, красивая печать, % отладка , управление историей, pylab , ... стоит потратить время на то, чтобы хорошо научиться.

13
ответ дан 22 November 2019 в 20:19
поделиться

Не очень скрыто, но функции имеют атрибуты:

def doNothing():
    pass

doNothing.monkeys = 4
print doNothing.monkeys
4
19
ответ дан 22 November 2019 в 20:19
поделиться

Extending properties (defined as descriptor) in subclasses

Sometimes it's useful to extent (modify) value "returned" by descriptor in subclass. It can be easily done with super():

class A(object):
    @property
    def prop(self):
        return {'a': 1}

class B(A):
    @property
    def prop(self):
        return dict(super(B, self).prop, b=2)

Store this in test.py and run python -i test.py (another hidden feature: -i option executed the script and allow you to continue in interactive mode):

>>> B().prop
{'a': 1, 'b': 2}
12
ответ дан 22 November 2019 в 20:19
поделиться

Python может понимать любые цифры в Юникоде , а не только в формате ASCII:

>>> s = u'10585'
>>> s
u'\uff11\uff10\uff15\uff18\uff15'
>>> print s
10585
>>> int(s)
10585
>>> float(s)
10585.0
15
ответ дан 22 November 2019 в 20:19
поделиться

Мод корректно работает с отрицательными числами

-1% 5 равно 4 , как и должно быть, а не -1, как в других языках, таких как JavaScript. Это делает «витые окна» более чистыми в Python, вы просто делаете это:

index = (index + increment) % WINDOW_SIZE
20
ответ дан 22 November 2019 в 20:19
поделиться

Угадывание целочисленной базы

>>> int('10', 0)
10
>>> int('0x10', 0)
16
>>> int('010', 0)  # does not work on Python 3.x
8
>>> int('0o10', 0)  # Python >=2.6 and Python 3.x
8
>>> int('0b10', 0)  # Python >=2.6 and Python 3.x
2
13
ответ дан 22 November 2019 в 20:19
поделиться

itertools

Этот модуль часто упускают из виду. В следующем примере используется itertools.chain(). чтобы сгладить список:

>>> from itertools import *
>>> l = [[1, 2], [3, 4]]
>>> list(chain(*l))
[1, 2, 3, 4]

См. http://docs.python.org/library/itertools.html#recipes для получения дополнительной информации о приложениях.

.
14
ответ дан 22 November 2019 в 20:19
поделиться

Управление sys.modules

Вы можете управлять кешем модулей напрямую, делая модули доступными или недоступными по своему усмотрению:

>>> import sys
>>> import ham
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named ham

# Make the 'ham' module available -- as a non-module object even!
>>> sys.modules['ham'] = 'ham, eggs, saussages and spam.'
>>> import ham
>>> ham
'ham, eggs, saussages and spam.'

# Now remove it again.
>>> sys.modules['ham'] = None
>>> import ham
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named ham

Это работает даже для модулей что доступны , и в некоторой степени для модулей, которые уже импортированы :

>>> import os
# Stop future imports of 'os'.
>>> sys.modules['os'] = None
>>> import os
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named os
# Our old imported module is still available.
>>> os
<module 'os' from '/usr/lib/python2.5/os.pyc'>

Как видно из последней строки, изменение sys.modules влияет только на будущий импорт операторы, а не прошлые, поэтому, если вы хотите повлиять на другие модули, важно внести эти изменения до , вы даете им возможность попробовать импортировать модули - так что, как правило, перед их импортом. Нет - специальное значение в sys.modules , используемое для отрицательного кэширования (указывающее, что модуль не был найден в первый раз, поэтому нет смысла искать снова). Любое другое значение будет быть результатом операции import - даже если это не объект модуля. Вы можете использовать это для замены модулей объектами, которые ведут себя точно так, как вы хотите. Удаление записи из sys.modules полностью приводит к тому, что следующий import выполняет обычный поиск модуля, даже если он уже был импортирован ранее.

14
ответ дан 22 November 2019 в 20:19
поделиться

Передача кортежа встроенным функциям

Многие функции Python принимают кортежи, что тоже не похоже. Например, вы хотите проверить, является ли ваша переменная числом, вы можете сделать:

if isinstance (number, float) or isinstance (number, int):  
   print "yaay"

Но если вы передадите нам кортеж, это будет выглядеть намного чище:

if isinstance (number, (float, int)):  
   print "yaay"
19
ответ дан 22 November 2019 в 20:19
поделиться

Хорошая обработка бесконечной рекурсии в словарях:

>>> a = {}
>>> b = {}
>>> a['b'] = b
>>> b['a'] = a
>>> print a
{'b': {'a': {...}}}
19
ответ дан 22 November 2019 в 20:19
поделиться

Множественные ссылки на итератор

Вы можете создать несколько ссылок на один и тот же итератор, используя умножение списка:

>>> i = (1,2,3,4,5,6,7,8,9,10) # or any iterable object
>>> iterators = [iter(i)] * 2
>>> iterators[0].next()
1
>>> iterators[1].next()
2
>>> iterators[0].next()
3

Это может быть использовано для группировки итератора в куски, например, как в этом примере из документации itertools

def grouper(n, iterable, fillvalue=None):
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)
17
ответ дан 22 November 2019 в 20:19
поделиться

Вы можете спросить любой объект, из какого модуля он пришел, посмотрев на его свойство __ module__. Это полезно, например, если вы экспериментируете с командной строкой и много чего импортировали.

Аналогичным образом вы можете спросить модуль, откуда он взялся, посмотрев на его свойство __ file__. Это полезно при отладке проблем с путями.

14
ответ дан 22 November 2019 в 20:19
поделиться

реверсирование итерабельной переменной с использованием отрицательного шага

>>> s = "Hello World"
>>> s[::-1]
'dlroW olleH'
>>> a = (1,2,3,4,5,6)
>>> a[::-1]
(6, 5, 4, 3, 2, 1)
>>> a = [5,4,3,2,1]
>>> a[::-1]
[1, 2, 3, 4, 5]
18
ответ дан 22 November 2019 в 20:19
поделиться

При использовании интерактивной оболочки "_" содержит значение последнего напечатанного элемента:

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> _
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
22
ответ дан 22 November 2019 в 20:19
поделиться

Из словаря python 3.1 (2.7) поддерживаются определения наборов:

{ a:a for a in range(10) }
{ a for a in range(10) }
17
ответ дан 22 November 2019 в 20:19
поделиться

Утилита textwrap.dedent в python может оказаться весьма полезной при проверке того, что возвращаемая многострочная строка равна ожидаемому выводу без нарушения отступов в ваших unittests:

import unittest, textwrap

class XMLTests(unittest.TestCase):
    def test_returned_xml_value(self):
        returned_xml = call_to_function_that_returns_xml()
        expected_value = textwrap.dedent("""\
        <?xml version="1.0" encoding="utf-8"?>
        <root_node>
            <my_node>my_content</my_node>
        </root_node>
        """)

        self.assertEqual(expected_value, returned_xml)
22
ответ дан 22 November 2019 в 20:19
поделиться

Лямбда-выражения с нулевым аргументом и переменным аргументом

Лямбда-функции обычно используются для быстрого преобразования одного значения в другое, но их также можно использовать для обертывания значения в функции:

>>> f = lambda: 'foo'
>>> f()
'foo'

Они также могут принимать обычный синтаксис * args и ** kwargs :

>>> g = lambda *args, **kwargs: args[0], kwargs['thing']
>>> g(1, 2, 3, thing='stuff')
(1, 'stuff')
22
ответ дан 22 November 2019 в 20:19
поделиться

threading.enumerate () предоставляет доступ ко всем объектам Thread в системе, а sys._current_frames () возвращает текущие кадры стека всех потоков в системе, поэтому объедините эти два, и вы получите дампы стека в стиле Java:

def dumpstacks(signal, frame):
    id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
    code = []
    for threadId, stack in sys._current_frames().items():
        code.append("\n# Thread: %s(%d)" % (id2name[threadId], threadId))
        for filename, lineno, name, line in traceback.extract_stack(stack):
            code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
            if line:
                code.append("  %s" % (line.strip()))
    print "\n".join(code)

import signal
signal.signal(signal.SIGQUIT, dumpstacks)

Сделайте это в начале многопоточной программы на Python, и вы получите доступ к текущему состоянию потоков в любое время, отправив SIGQUIT. Вы также можете выбрать signal.SIGUSR1 или signal.SIGUSR2.

См.

8
ответ дан 22 November 2019 в 20:19
поделиться

Перезагрузка модулей включает стиль «живого кодирования». Но экземпляры класса не обновляются. Вот почему и как это обойти. Помните, все, да, все - это объект.

>>> from a_package import a_module
>>> cls = a_module.SomeClass
>>> obj = cls()
>>> obj.method()
(old method output)

Теперь вы меняете метод в a_module.py и хотите обновить свой объект.

>>> reload(a_module)
>>> a_module.SomeClass is cls
False # Because it just got freshly created by reload.
>>> obj.method()
(old method output)

Вот один из способов обновить его (но считайте, что он запущен с ножницами):

>>> obj.__class__ is cls
True # it's the old class object
>>> obj.__class__ = a_module.SomeClass # pick up the new class
>>> obj.method()
(new method output)

Это «бег ножницами», потому что внутреннее состояние объекта может отличаться от того, что ожидает новый класс. Это работает для действительно простых случаев, но помимо этого pickle - ваш друг. Тем не менее, полезно понять, почему это работает.

7
ответ дан 22 November 2019 в 20:19
поделиться