source

Python의 숨겨진 기능

nicesource 2023. 1. 19. 06:59
반응형

Python의 숨겨진 기능

Python 프로그래밍 언어의 잘 알려지지 않았지만 유용한 기능은 무엇입니까?

  • Python core에 대한 답변을 제한해 보십시오.
  • 응답마다 1개의 기능이 있습니다.
  • 설명서에 대한 링크뿐만 아니라 기능에 대한 예시와 간단한 설명을 제공하십시오.
  • 첫 번째 행으로 제목을 사용하여 피쳐에 라벨을 붙입니다.

답변에 대한 빠른 링크:

체인 비교 연산자:

>>> 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단, 입력 횟수가 적고 각 용어는 한 번만 평가됩니다.

python regex 구문 분석 트리를 가져와 regex를 디버깅합니다.

정규 표현은 python의 큰 특징이지만 디버깅은 번거로울 수 있으며 regex를 틀리기 쉽습니다.

되어 있지 않은 플래그를 트리를 할 수 .re.DEBUG)~re.compile.

>>> re.compile("^\[font(?:=(?P<size>[-+][0-9]{1,2}))?\](.*?)[/font]",
    re.DEBUG)
at at_beginning
literal 91
literal 102
literal 111
literal 110
literal 116
max_repeat 0 1
  subpattern None
    literal 61
    subpattern 1
      in
        literal 45
        literal 43
      max_repeat 1 2
        in
          range (48, 57)
literal 93
subpattern 2
  min_repeat 0 65535
    any None
in
  literal 47
  literal 102
  literal 111
  literal 110
  literal 116

구문을 이해하면 오류를 발견할 수 있습니다., 내가 을 알 수 .[][/font].

물론 주석 첨부 정규식처럼 원하는 플래그와 결합할 수 있습니다.

>>> re.compile("""
 ^              # start of a line
 \[font         # the font tag
 (?:=(?P<size>  # optional [font=+size]
 [-+][0-9]{1,2} # size specification
 ))?
 \]             # end of tag
 (.*?)          # text between the tags
 \[/font\]      # end of the tag
 """, re.DEBUG|re.VERBOSE|re.DOTALL)

열거하다

반복 가능한 항목을 열거형으로 감싸면 항목이 인덱스와 함께 생성됩니다.

예를 들어 다음과 같습니다.


>>> a = ['a', 'b', 'c', 'd', 'e']
>>> for index, item in enumerate(a): print index, item
...
0 a
1 b
2 c
3 d
4 e
>>>

참고 자료:

생성기 개체 생성

쓰시면

x=(n for n in foo if bar(n))

발전기를 꺼내서 x에 할당할 수 있습니다. 이제 이것은 당신이

for n in x:

이 방법의 장점은 중간 스토리지가 필요하지 않다는 것입니다. 중간 스토리지는 필요 없습니다.

x = [n for n in foo if bar(n)]

경우에 따라서는, 이것에 의해 속도가 큰폭으로 향상하는 일이 있습니다.

생성기 끝에 여러 if 문을 추가할 수 있으며 기본적으로 루프를 위해 중첩된 것을 복제할 수 있습니다.

>>> 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)

iter()는 콜 가능한 인수를 사용할 수 있습니다.

예:

def seek_next_line(f):
    for c in iter(lambda: f.read(1),'\n'):
        pass

iter(callable, until_value) 호출하다callable 를 낳다until_value이 반환됩니다.

가변 기본 인수에 주의하십시오.

>>> def foo(x=[]):
...     x.append(1)
...     print x
... 
>>> foo()
[1]
>>> foo()
[1, 1]
>>> foo()
[1, 1, 1]

대신 "not gived"를 나타내는 sentinel 값을 사용하고 기본값으로 사용할 변수로 대체합니다.

>>> def foo(x=None):
...     if x is None:
...         x = []
...     x.append(1)
...     print x
>>> foo()
[1]
>>> foo()
[1]

제너레이터 함수로 을 보내는 입니다.예를 들어 다음과 같은 기능이 있습니다.

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

범위를 나타내는 데 공백을 사용하지 않으려면 다음을 발행하여 C 스타일 {}을(를) 사용할 수 있습니다.

from __future__ import braces

슬라이스 연산자의 단계 인수입니다.예를 들어 다음과 같습니다.

a = [1,2,3,4,5]
>>> a[::2]  # iterate over the whole list in 2-increments
[1,3,5]

★★★★★★★★★★★★★★★★★★★★x[::-1]'x reverseed'는 'x reverse'를 말합니다.

>>> a[::-1]
[5,4,3,2,1]

데코레이터

데코레이터를 사용하면 기능을 추가하거나 인수 또는 결과를 수정할 수 있는 다른 함수로 함수 또는 메서드를 래핑할 수 있습니다.데코레이터는 함수 정의 위에 "at" 기호(@)로 시작하여 한 줄 위에 씁니다.

' '를 나타냅니다.print_args장식된 함수를 호출하기 전에 인수를 인쇄하는 데코레이터:

>>> def print_args(function):
>>>     def wrapper(*args, **kwargs):
>>>         print 'Arguments:', args, kwargs
>>>         return function(*args, **kwargs)
>>>     return wrapper

>>> @print_args
>>> def write(text):
>>>     print text

>>> write('foo')
Arguments: ('foo',) {}
foo

for...syslog 구문(http://docs.python.org/ref/for.html 참조)

for i in foo:
    if i == 0:
        break
else:
    print("i was never 0")

"else" 블록은 브레이크가 호출되지 않는 한 보통 for 루프의 끝에서 실행됩니다.

위의 코드는 다음과 같이 에뮬레이트할 수 있습니다.

found = False
for i in foo:
    if i == 0:
        found = True
        break
if not found: 
    print("i was never 0")

2.5 2.5가 .__missing__누락된 항목에 대해 호출됩니다.

>>> class MyDict(dict):
...  def __missing__(self, key):
...   self[key] = rv = []
...   return rv
... 
>>> m = MyDict()
>>> m["foo"].append(1)
>>> m["foo"].append(2)
>>> dict(m)
{'foo': [1, 2]}

dict에는 .collections라고 하는defaultdict는 거의 하지 않는합니다.

>>> from collections import defaultdict
>>> m = defaultdict(list)
>>> m["foo"].append(1)
>>> m["foo"].append(2)
>>> dict(m)
{'foo': [1, 2]}

이러한 서브클래스를 필요로 하지 않는 함수에 전달하기 전에 이러한 딕트를 일반 딕트로 변환할 것을 권장합니다.에서는 「 」를 사용하고 있습니다.d[a_key]KeyErrors를 캐치하여 새 항목을 dict에 추가하는 항목이 존재하는지 확인합니다.

임플레이스 값 스왑

>>> a = 10
>>> b = 5
>>> a, b
(10, 5)

>>> a, b = b, a
>>> a, b
(5, 10)

과제 오른쪽은 새로운 태플을 만드는 표현입니다.은, 그 되지 않은) 「」으로 전개합니다.a ★★★★★★★★★★★★★★★★★」b.

후 , 에 은 가비지 수집에 됩니다.a ★★★★★★★★★★★★★★★★★」b가 스왑 되었습니다.

데이터 구조에 대한 Python 튜토리얼 섹션에서 설명한 바와 같이,

여러 개의 할당은 실제로는 태플 패킹과 시퀀스 언팩의 조합일 뿐입니다.

읽기 쉬운 정규 표현식

Python에서는 정규식을 여러 줄로 분할하여 일치하는 이름을 지정하고 주석을 삽입할 수 있습니다.

상세 구문 예(Dive in Python에서):

>>> pattern = """
... ^                   # beginning of string
... M{0,4}              # thousands - 0 to 4 M's
... (CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
...                     #            or 500-800 (D, followed by 0 to 3 C's)
... (XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
...                     #        or 50-80 (L, followed by 0 to 3 X's)
... (IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
...                     #        or 5-8 (V, followed by 0 to 3 I's)
... $                   # end of string
... """
>>> re.search(pattern, 'M', re.VERBOSE)

(정규 표현 HOWTO에서) 일치하는 이름의 예

>>> p = re.compile(r'(?P<word>\b\w+\b)')
>>> m = p.search( '(((( Lots of punctuation )))' )
>>> m.group('word')
'Lots'

''을 쓰지 ''을쓸도 있어요.re.VERBOSE스트링 리터럴 연결 덕분입니다.

>>> pattern = (
...     "^"                 # beginning of string
...     "M{0,4}"            # thousands - 0 to 4 M's
...     "(CM|CD|D?C{0,3})"  # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
...                         #            or 500-800 (D, followed by 0 to 3 C's)
...     "(XC|XL|L?X{0,3})"  # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
...                         #        or 50-80 (L, followed by 0 to 3 X's)
...     "(IX|IV|V?I{0,3})"  # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
...                         #        or 5-8 (V, followed by 0 to 3 I's)
...     "$"                 # end of string
... )
>>> print pattern
"^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$"

함수 인수 압축 해제

로 풀 수.* ★★★★★★★★★★★★★★★★★」**.

예를 들어 다음과 같습니다.

def draw_point(x, y):
    # do some magic

point_foo = (3, 4)
point_bar = {'y': 3, 'x': 2}

draw_point(*point_foo)
draw_point(**point_bar)

목록, 튜플 및 딕트가 컨테이너로 널리 사용되므로 매우 유용합니다.

ROT13은 코드 파일 상단에 올바른 코딩 선언을 사용하는 경우 소스 코드의 유효한 인코딩입니다.

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

cevag "Uryyb fgnpxbiresybj!".rapbqr("rot13")

완전히 동적인 방법으로 새로운 유형 생성

>>> NewType = type("NewType", (object,), {"x": "hello"})
>>> n = NewType()
>>> n.x
"hello"

와 꼭 같다.

>>> class NewType(object):
>>>     x = "hello"
>>> n = NewType()
>>> n.x
"hello"

아마 가장 유용한 것은 아닐 테지만, 알게 되어 기쁩니다.

편집: 새 유형의 고정 이름, 다음 값이어야 합니다.NewTypeclass★★★★★★ 。

편집: 기능을 보다 정확하게 설명하기 위해 제목을 조정했습니다.

'콘텍스트 매니저'with" (영어)

PEP 343에서 도입컨텍스트 매니저는 일련의 스테이트먼트의 런타임콘텍스트로서 기능하는 오브젝트입니다.

이 기능은 새로운 키워드를 사용하기 때문에 점차 도입되어 디렉티브를 통해 Python 2.5에서 사용할 수 있습니다.Python 2.6 이상(Python 3 포함)은 기본적으로 사용할 수 있습니다.

"with" 문장은 매우 유용한 구성이라고 생각하기 때문에 많이 사용하고 있습니다.여기 간단한 데모가 있습니다.

from __future__ import with_statement

with open('foo.txt', 'w') as f:
    f.write('hello!')

이 뒤에서 일어나는 일은 "with"라는 문구가 특별함을 부른다는 겁니다__enter__ ★★★★★★★★★★★★★★★★★」__exit__메서드를 지정합니다.예외에 대한 자세한 내용은 다음에도 전달됩니다.__exit__With 스테이트먼트 본문에서 예외가 발생한 경우 예외 처리를 허용합니다.

이 의 때 됩니다.with스위트(정상적으로 발생하는지 또는 예외가 발생했는지 여부에 관계없이)를 지정합니다.이는 기본적으로 일반적인 예외 처리 코드를 추상화하는 방법입니다.

이 밖에 스레드 및 데이터베이스 트랜잭션에 의한 잠금이 일반적인 사용 사례로 제시됩니다.

사전에는 get() 메서드가 있습니다.

사전에는 'get()' 메서드가 있습니다.d['key']를 실행했는데 키가 없으면 예외가 발생합니다.d.get('key')를 실행하면 'key'가 없으면 None이 반환됩니다.None 대신 두 번째 인수를 추가하여 해당 항목을 되돌릴 수 있습니다(예: d.get('key', 0).

숫자를 더하는 등의 작업에 매우 적합합니다.

sum[value] = sum.get(value, 0) + 1

디스크립터

Python의 많은 핵심 기능 뒤에 있는 마법입니다.

도트 액세스를 사용하여 멤버(예: x.y)를 조회하면 Python은 먼저 인스턴스 사전에서 멤버를 찾습니다.찾을 수 없는 경우 클래스 사전에서 찾습니다.클래스 사전에서 찾은 개체에서 설명자 프로토콜을 구현하는 경우 Python은 이를 단순히 반환하는 대신 실행합니다.(descriptor)는 스크음음음음음을 입니다.__get__,__set__ , 「」__delete__★★★★★★★★★★★★★★★★★★.

디스크립터를 사용하여 독자적인(읽기 전용) 버전의 속성을 구현하는 방법은 다음과 같습니다.

class Property(object):
    def __init__(self, fget):
        self.fget = fget

    def __get__(self, obj, type):
        if obj is None:
            return self
        return self.fget(obj)

내장 프로퍼티()와 같이 사용할 수 있습니다.

class MyClass(object):
    @Property
    def foo(self):
        return "Foo!"

기술자는 속성, 바인딩 메서드, 정적 메서드, 클래스 메서드 및 슬롯을 구현하기 위해 Python에서 사용됩니다.그것들을 이해하면 Python의 'quirks'처럼 보였던 많은 것들이 왜 그런지 쉽게 알 수 있다.

레이먼드 헤팅어는 나보다 훨씬 더 잘 설명하는 훌륭한 튜토리얼을 가지고 있다.

조건부 할당

x = 3 if (y == 1) else 2

"y가 1이면 3을 x로 할당하고 그렇지 않으면 2를 x로 할당"과 같은 동작을 합니다.패런은 필수는 아니지만 읽기 쉽기 때문에 마음에 듭니다.보다 복잡한 것이 있는 경우는, 체인으로 할 수도 있습니다.

x = 3 if (y == 1) else 2 if (y == -1) else 1

어느 시점에서는 좀 지나치긴 하지만요.

다음 경우에 사용할 수 있습니다.어떤 식으로든요.예를 들어 다음과 같습니다.

(func1 if y == 1 else func2)(arg1, arg2) 

여기서 y가 1이면 func1이 호출되고 그렇지 않으면 func2가 호출됩니다.어느 경우든 대응하는 함수는 인수 arg1과 arg2를 사용하여 호출됩니다.

마찬가지로 다음 사항도 유효합니다.

x = (class1 if y == 1 else class2)(arg1, arg2)

여기서 class1과 class2는 2개의 클래스입니다.

Doctest: 문서화와 유닛 테스트를 동시에 실시합니다.

Python 문서에서 추출한 예:

def factorial(n):
    """Return the factorial of n, an exact integer >= 0.

    If the result is small enough to fit in an int, return an int.
    Else return a long.

    >>> [factorial(n) for n in range(6)]
    [1, 1, 2, 6, 24, 120]
    >>> factorial(-1)
    Traceback (most recent call last):
        ...
    ValueError: n must be >= 0

    Factorials of floats are OK, but the float must be an exact integer:
    """

    import math
    if not n >= 0:
        raise ValueError("n must be >= 0")
    if math.floor(n) != n:
        raise ValueError("n must be exact integer")
    if n+1 == n:  # catch a value like 1e300
        raise OverflowError("n too large")
    result = 1
    factor = 2
    while factor <= n:
        result *= factor
        factor += 1
    return result

def _test():
    import doctest
    doctest.testmod()    

if __name__ == "__main__":
    _test()

이름 있는 포맷

% - 포맷에는 사전이 필요합니다(%i/%s 등의 유효성 검사도 적용됩니다).

>>> print "The %(foo)s is %(bar)i." % {'foo': 'answer', 'bar':42}
The answer is 42.

>>> foo, bar = 'question', 123

>>> print "The %(foo)s is %(bar)i." % locals()
The question is 123.

locals()도 사전이므로 dict로 전달하고 로컬 변수에서 % -substitions를 사용할 수 있습니다.내 생각에 이건 눈살을 찌푸리게 하는 것 같아. 하지만 간단해.

새로운 스타일 포맷

>>> print("The {foo} is {bar}".format(foo='answer', bar=42))

더 많은 파이썬 모듈(특히 서드파티 모듈)을 추가하기 위해 대부분의 사람들은 PYTONPATH 환경변수를 사용하거나 사이트 패키지 디렉토리에 심볼링크 또는 디렉토리를 추가하는 것으로 보입니다.또 다른 방법은 *.pth 파일을 사용하는 것입니다.공식 Python Doc의 설명은 다음과 같습니다.

"[파이썬의 검색 경로를 수정하는] 가장 편리한 방법은 Python의 경로에 이미 있는 디렉토리, 보통 .../site-packages/ 디렉토리에 경로 구성 파일을 추가하는 것입니다.경로 컨피규레이션파일의 확장자는 .pth이며 각 행에는 sys.path에 추가할 경로가1개 포함되어 있어야 합니다.(새 경로가 sys.path에 추가되기 때문에 추가된 디렉토리의 모듈은 표준 모듈을 덮어쓰지 않습니다.즉, 이 메커니즘을 사용하여 표준 모듈의 고정 버전을 설치할 수 없습니다.)"

예외 else 절:

try:
  put_4000000000_volts_through_it(parrot)
except Voom:
  print "'E's pining!"
else:
  print "This parrot is no more!"
finally:
  end_sketch()

else 구를 사용하면 try 구에 코드를 추가하는 것보다 더 좋습니다. 왜냐하면 try에 의해 보호되는 코드에 의해 발생하지 않은 예외가 우연히 포착되는 것을 방지할 수 있기 때문입니다.스테이트먼트를 제외합니다.

http://docs.python.org/tut/node10.html 를 참조해 주세요.

예외 다시 제기:

# 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)

오류 핸들러 내부에 인수가 없는 'raise' 문은 Python에게 원래 트레이스백을 그대로 두고 예외를 다시 올리도록 지시하며, "오, 죄송합니다, 죄송합니다, 죄송합니다, 죄송합니다."라고 말할 수 있습니다.

원본 트레이스백을 인쇄, 저장 또는 만지작거리고 싶다면 sys.exc_info()를 사용하여 얻을 수 있습니다.Python처럼 인쇄하면 'traceback' 모듈을 사용할 수 있습니다.

주요 메시지:)

import this
# btw look at this module's source :)

디사이퍼:

Python의 Zen, Tim Peters의

하다
하다
하다
을 사용하다
하다
을 사용하다
가독성이 중요합니다.
특별한 경우는 규칙을 어길 만큼 특별하지 않다.
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
오류는 절대 묵살해서는 안 됩니다.
명시적으로 침묵하지 않는 한.
애매모호함에 직면하여 추측의 유혹을 거부하라.그것을 할 수 있는 확실한 방법은 하나, 그리고 가급적 하나뿐이어야 합니다.
네덜란드인이 아니라면 처음엔 그렇게 티가 나지 않을 수도 있지만요.
안 하는 것보다는 지금이 낫다.
하지만 지금보다 더 나은 경우는 없다.
구현에 대해 설명하기 어렵다면 이는 잘못된 생각입니다.
구현에 대해 설명하기 쉽다면 좋은 생각일 수 있습니다.
네임스페이스는 경적을 울리는 좋은 아이디어 중 하나입니다.!!들!!!!

인터랙티브 인터프리터 탭 완료

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()

PYTON STARTUP 환경변수도 설정해야 합니다.

중첩된 목록 압축 및 생성기 식:

[(i,j) for i in range(3) for j in range(i) ]    
((i,j) for i in range(4) for j in range(i) )

이들은 네스트 루프 코드의 거대한 청크를 대체할 수 있습니다.

" " "의 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}

표준 라이브러리 참조의 자세한 내용은 다음과 같습니다.유형 설정

언급URL : https://stackoverflow.com/questions/101268/hidden-features-of-python

반응형