Поскольку язык программирования Go не поддерживает в настоящее время общие типы, это будет трудно сделать.
В какой-то момент вполне могут быть добавлены дженерики. Мы не чувствуем для них неотложности, хотя мы понимаем, что некоторые программисты это делают.
Дженерики удобны, но они сложны по сложности в системе типов и времени выполнения. Мы еще не нашли дизайн, который дает ценность, пропорциональную сложности, хотя мы продолжаем думать об этом. Между тем, встроенные карты и фрагменты Go, а также возможность использования пустого интерфейса для создания контейнеров (с явным распаковкой) означают, что во многих случаях можно написать код, который будет делать какие дженерики будут разрешены, если будет менее плавным.
Это остается открытой проблемой.
blockquote>Посмотрите на пакет сортировки Go , чтобы увидеть, как он обрабатывает сравнения и другие операции, относящиеся к типу, путем определения sort.Interface с методами Len, Less и Swap.
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>
Создание словаря двух последовательностей, которые связали данные
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}
Объекты маленького 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
>>>
ROT13 является допустимой кодировкой для исходного кода, если вы используете правильное объявление кодировки в верхней части файла кода:
#!/usr/bin/env python
# -*- coding: rot13 -*-
cevag "Uryyb fgnpxbiresybj!".rapbqr("rot13")
Тот факт, что вы можете вызывать функцию каждый раз, когда что-то соответствует регулярному выражению, очень удобен. Здесь у меня есть пример замены каждого «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?'
Синтаксис распаковки был обновлен в последней версии, как показано в примере.
>>> 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)
Умножение на логическое значение
Одна вещь, которую я постоянно делаю в веб-разработке, - это дополнительная печать параметров HTML. Мы все видели такой код на других языках:
class='<% isSelected ? "selected" : "" %>'
В Python вы можете умножать на логическое значение, и он делает именно то, что вы ожидаете:
class='<% "selected" * isSelected %>'
Это потому, что умножение переводит логическое значение в целое число (0 для False, 1 для True), а в python умножение строки на int повторяет строку N раз.
Этот ответ был перемещен в сам вопрос по просьбе многих людей.
Многострочные строки
Один из подходов - использовать обратную косую черту:
>>> 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
).
Существует менее известный третий аргумент встроенной функции pow()
, который позволяет вычислять xy по модулю z более эффективно, чем простое выполнение (x ** y) % z
:
>>> x, y, z = 1234567890, 2345678901, 17
>>> pow(x, y, z) # almost instantaneous
6
Для сравнения, (x ** y) % z
для тех же значений не дал результата за одну минуту на моей машине.
Мне лично нравятся 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
Одно слово: IPython
Самоанализ вкладки, красивая печать, % отладка
, управление историей, pylab
, ... стоит потратить время на то, чтобы хорошо научиться.
Не очень скрыто, но функции имеют атрибуты:
def doNothing():
pass
doNothing.monkeys = 4
print doNothing.monkeys
4
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}
Python может понимать любые цифры в Юникоде , а не только в формате ASCII:
>>> s = u'10585'
>>> s
u'\uff11\uff10\uff15\uff18\uff15'
>>> print s
10585
>>> int(s)
10585
>>> float(s)
10585.0
Мод корректно работает с отрицательными числами
-1% 5 равно 4 , как и должно быть, а не -1, как в других языках, таких как JavaScript. Это делает «витые окна» более чистыми в Python, вы просто делаете это:
index = (index + increment) % WINDOW_SIZE
Угадывание целочисленной базы
>>> 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
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 для получения дополнительной информации о приложениях.
.Вы можете управлять кешем модулей напрямую, делая модули доступными или недоступными по своему усмотрению:
>>> 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
выполняет обычный поиск модуля, даже если он уже был импортирован ранее.
Многие функции Python принимают кортежи, что тоже не похоже. Например, вы хотите проверить, является ли ваша переменная числом, вы можете сделать:
if isinstance (number, float) or isinstance (number, int):
print "yaay"
Но если вы передадите нам кортеж, это будет выглядеть намного чище:
if isinstance (number, (float, int)):
print "yaay"
Хорошая обработка бесконечной рекурсии в словарях:
>>> a = {}
>>> b = {}
>>> a['b'] = b
>>> b['a'] = a
>>> print a
{'b': {'a': {...}}}
Множественные ссылки на итератор
Вы можете создать несколько ссылок на один и тот же итератор, используя умножение списка:
>>> 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)
Вы можете спросить любой объект, из какого модуля он пришел, посмотрев на его свойство __ module__. Это полезно, например, если вы экспериментируете с командной строкой и много чего импортировали.
Аналогичным образом вы можете спросить модуль, откуда он взялся, посмотрев на его свойство __ file__. Это полезно при отладке проблем с путями.
реверсирование итерабельной переменной с использованием отрицательного шага
>>> 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]
При использовании интерактивной оболочки "_" содержит значение последнего напечатанного элемента:
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> _
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>
Из словаря python 3.1 (2.7) поддерживаются определения наборов:
{ a:a for a in range(10) }
{ a for a in range(10) }
Утилита 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)
Лямбда-функции обычно используются для быстрого преобразования одного значения в другое, но их также можно использовать для обертывания значения в функции:
>>> f = lambda: 'foo'
>>> f()
'foo'
Они также могут принимать обычный синтаксис * args
и ** kwargs
:
>>> g = lambda *args, **kwargs: args[0], kwargs['thing']
>>> g(1, 2, 3, thing='stuff')
(1, 'stuff')
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.
Перезагрузка модулей включает стиль «живого кодирования». Но экземпляры класса не обновляются. Вот почему и как это обойти. Помните, все, да, все - это объект.
>>> 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
- ваш друг. Тем не менее, полезно понять, почему это работает.