파이썬코딩

파이썬코딩 format binary data etc

Format 

 

우리는 지금까지 텍스트 서식을 거의 무시해 왔다. 2장에는 몇 가지 문자열 정렬 기능이 나와 있으며 코드 예제는 간단한 인쇄() 문을 사용하거나 대화형 인터프리터가 값을 표시하도록 합니다. 하지만 이제는 다양한 형식을 사용하여 데이터 값을 문자열로 변환하는 방법, 즉 문자열 내부에 값을 넣는 방법에 대해 알아보아야 합니다. 이를 통해 보고서 및 기타 출력물을 생성할 수 있으며, 이를 위해 분배가 필요할 수 있습니다.

 

Python은 문자열을 포맷하는 두 가지 방법, 즉 느슨하게 옛날 스타일과 새로운 스타일이라고 불린다. 두 스타일 모두 Python 2 및 3에서 지원됩니다(Python 2.6 이상의 새로운 스타일). 구식이 더 간단하니까 거기서부터 시작하죠.

이전 스타일(% 포함)

이전 스타일의 문자열 형식에는 형식 문자열% 데이터가 있습니다. 문자열 내부에는 보간 시퀀스가 있습니다. 아래는 가장 간단한 시퀀스가 % 다음에 형식화할 데이터 유형을 나타내는 문자가 있음을 보여준다.

 

%s string
%d decimal integer
%x hex integer
%o octal integer
%f decimal float
%e exponential float
%g decimal or exponential float %% a literal% 

 

다음은 몇 가지 간단한 예입니다. 첫째, 정수:

 

>>> '%s' % 42

    '42'

    >>> '%d' % 42

    '42'

    >>> '%x' % 42

    '2a'

    >>> '%o' % 42

    '52'

 

플로트:

 

 >>> '%s' % 7.03

    '7.03'

    >>> '%f' % 7.03

    '7.030000'

    >>> '%e' % 7.03

    '7.030000e+00'

    >>> '%g' % 7.03

    '7.03'

 

정수 및 리터럴 %:

 

>>> '%d%%' % 100 

'100%' 

 

일부 문자열 및 정수 보간법:

 

  >>> actor = 'Richard Gere'

    >>> cat = 'Chester'

    >>> weight = 28

    >>> "My wife's favorite actor is %s" % actor

    "My wife's favorite actor is Richard Gere"

    >>> "Our cat %s weighs %s pounds" % (cat, weight)

    'Our cat Chester weighs 28 pounds'

 

문자열 내부의 %s은 문자열을 보간한다는 의미입니다. 문자열에 나타나는 % 개수는 % 이후의 데이터 항목 개수와 일치합니다. 행위자와 같은 단일 데이터 항목은 % 바로 뒤에 있습니다. (cat, weight)와 같은 튜플(괄호로 묶고 쉼표로 구분)로 여러 데이터를 그룹화해야 합니다.

 

가중치가 정수임에도 불구하고 문자열 안에 있는 %s이(가) 문자열로 변환했습니다.
%와 형식 지정자 사이에 다른 값을 추가하여 최소값을 지정할 수 있습니다.

최대 너비, 정렬 및 문자 채우기:
변수의 경우 정수 n, 플로트 f 및 문자열 s를 정의하겠습니다.

 

>>>n=42 >>>f=7.03
>>> s = 'string cheese' 

 

기본 너비를 사용하여 형식 지정:

 

>>>'%d%f%s'%(n,f,s) '42 7.030000 string cheese' 

 

각 변수에 대해 최소 필드 너비를 10자로 설정하고 오른쪽에 정렬하여 왼쪽의 사용되지 않는 부분을 공백으로 채웁니다.

 

  >>> '%10d %10f %10s' % (n, f, s)

    '        42   7.030000 string cheese'

 

동일한 필드 너비를 사용하지만 왼쪽으로 정렬합니다.

 

 >>> '%-10d %-10f %-10s' % (n, f, s)

    '42         7.030000   string cheese'

 

이번에는 필드 너비는 같지만 최대 문자 너비는 4이고 오른쪽에 정렬됩니다. 이 설정을 사용하면 문자열이 잘리고 소수점 뒤의 부동자리가 4자리로 제한됩니다.

 

  >>> '%10.4d %10.4f %10.4s' % (n, f, s)

    '      0042     7.0300       stri'

 

이전과 동일하지만, 오른쪽 정렬:

 

   >>> '%.4d %.4f %.4s' % (n, f, s)

    '0042 7.0300 stri'

 

마지막으로, 인수에서 필드 너비를 하드 코딩하지 않고 가져옵니다.

 

  >>> '%*.*d %*.*f %*.*s' % (10, 4, n, 10, 4, f, 10, 4, s)

    '      0042     7.0300       stri'

 

New style formatting with {} and format 

 

이전 스타일 형식은 여전히 지원됩니다. 버전 2.7에서 동결되는 파이썬 2에서는 영원히 지원될 것이다. 그러나 파이썬 3을 사용하는 경우에는 새로운 스타일 포맷이 권장됩니다.

가장 간단한 용법은 다음과 같습니다.

 

  >>> '{} {} {}'.format(n, f, s)

    '42 7.03 string cheese'

 

이전 형식의 인수는 해당 자리 표시자의 %가 문자열에 나타나는 순서로 제공되어야 합니다. 새 유형을 사용하여 순서를 지정할 수 있습니다.

   

>>> '{2} {0} {1}'.format(f, s, n)

    '42 7.03 string cheese'

 

값 0은 첫 번째 인수인 f를 가리킨 반면, 1은 문자열 s를 가리켰고 2는 마지막 인수인 정수 n을 가리켰습니다.

인수는 사전 또는 명명된 인수일 수 있으며 지정자에는 다음과 같은 인수의 이름이 포함될 수 있습니다.

 

>>> '{n} {f} {s}'.format(n=42, f=7.03, s='string cheese')

    '42 7.03 string cheese'

 

다음 예에서는 세 가지 값을 사전으로 결합해 보겠습니다. 다음과 같습니다.

 

>>> d = {'n': 42, 'f': 7.03, 's': 'string cheese'}

 

다음 예제에서 {0}은(는) 전체 사전이고 {1}은(는) 문자열 '기타'입니다.

사전 다음에 나오는 내용:

   

>>> '{0[n]} {0[f]} {0[s]} {1}'.format(d, 'other')

    '42 7.03 string cheese other'

 

이 예들은 모두 기본 형식으로 인수를 인쇄했습니다. 이전 형식에서는 문자열의 % 뒤에 형식 지정자를 사용할 수 있지만 새 형식에서는 : 뒤에 붙입니다. 첫째, 위치 인수:

 

  >>> '{0:d} {1:f} {2:s}'.format(n, f, s)

    '42 7.030000 string cheese'

 

이 예에서는 동일한 값을 사용하지만 명명된 인수와 같습니다.

  

>>> '{n:d} {f:f} {s:s}'.format(n=42, f=7.03, s='string cheese')

    '42 7.030000 string cheese'

 

다른 옵션(최소 필드 너비, 최대 문자 너비, 정렬 등)도 지원됩니다.

최소 필드 너비 10, 오른쪽 정렬(기본값):

 

  >>> '{0:10d} {1:10f} {2:10s}'.format(n, f, s)

    '        42   7.030000 string cheese'

 

앞의 예제와 동일하지만 > 문자는 오른쪽 정렬을 더 명확하게 만듭니다.

 

 >>> '{0:>10d} {1:>10f} {2:>10s}'.format(n, f, s)

    '        42   7.030000 string cheese'

 

최소 필드 폭 10, 왼쪽 정렬:

 

  >>> '{0:<10d} {1:<10f} {2:<10s}'.format(n, f, s)

    '42         7.030000   string cheese'

 

최소 필드 폭 10, 가운데:

 

>>> '{0:^10d} {1:^10f} {2:^10s}'.format(n, f, s)

    '    42      7.030000  string cheese'

 

이전 스타일에서 한 가지 변경 사항이 있습니다. 즉, 소수점 뒤의 정밀도 값은 부동 소수점 뒤의 자릿수와 문자열의 최대 문자 수를 의미하지만 정수에 대해서는 사용할 수 없습니다.

 

  >>> '{0:>10.4d} {1:>10.4f} {2:10.4s}'.format(n, f, s)

    Traceback (most recent call last):

File "<stdin>", line 1, in <module>
ValueError: Precision not allowed in integer format specifier >>> '{0:>10d} {1:>10.4f} {2:>10.4s}'.format(n, f, s)
' 42 7.0300 stri' 

 

마지막 옵션은 채우기 문자입니다. 공백이 아닌 다른 출력 필드를 채우려면 :, 정렬(<, >, ^) 또는 너비 지정 피어 바로 앞에 놓습니다.

 

>>> '{0:!^20s}'.format('BIG SALE')

    '!!!!!!BIG SALE!!!!!!'

 

Match with Regular Expressions 

이전포스팅에서는 간단한 문자열 연산에 대해 다루었다. 입문 정보로 무장한 여러분은 명령행에서 .py로 끝나는 모든 파일 이름을 나열하는 것을 의미하는 ls *.py와 같은 단순한 "와일드카드" 패턴을 사용해 본 적이 있을 것이다.

이제 정규식을 사용하여 더 복잡한 패턴 일치를 살펴볼 차례입니다. 이것들은 우리가 수입할 표준 모듈 re에 제공된다. 일치시킬 문자열 패턴과 일치시킬 소스 문자열을 정의합니다. 단순 일치의 경우 용도는 다음과 같습니다.

 

result = re.match('You', 'Young Frankenstein')

여기서 'You'가 패턴이고 'Young Frankenstein'이 그 근원이다. 즉, 당신이 만든 끈이다.

want to check. match()는 소스가 패턴으로 시작하는지 여부를 확인합니다.

더 복잡한 일치의 경우 먼저 패턴을 컴파일하여 일치 속도를 높일 수 있습니다.

나중에:

 

youpattern = re.compile('You')

그런 다음 컴파일된 패턴에 대해 일치를 수행할 수 있습니다.

 result = youpattern.match('Young Frankenstein')

match()만이 패턴과 소스를 비교하는 유일한 방법은 아니다. 다음은 사용할 수 있는 몇 가지 다른 방법입니다.

• 검색 결과 첫 번째 일치 항목이 있는 경우 반환됩니다.

• findall은 모든 비반복 일치 항목(있는 경우) 목록을 반환합니다.

• 분할은 패턴과 일치할 때 소스를 분할하고 문자열 조각 목록을 반환합니다.

• 하위 항목에서는 다른 교체 인수를 사용하여 패턴별로 일치하는 소스의 모든 부분을 교체로 변경합니다.

 

Exact match with match() 

'Young Frankenstein'이라는 문자열은 'You'라는 단어로 시작되나요? 설명과 함께 몇 가지 코드가 있습니다.

>>> import re
>>> source = 'Young Frankenstein'
>>> m = re.match('You', source) # match starts at the beginning of source >>> if m: # match returns an object; do this to see what matched
... print(m.group())
...
You
>>> m = re.match('^You', source) # start anchor does the same
>>> if m:
... print(m.group())
...
You 

'프랭크'는 어때?

>>> m = re.match('Frank', source) >>> if m:
... print(m.group())
... 

이번에는 일치하는()이 반환되지 않았고 if가 인쇄 문을 실행하지 않았습니다. 앞에서 말했듯이 패턴이 원본의 시작 부분에 있을 경우에만 일치()가 작동합니다. 그러나 패턴이 있는 경우 검색()이 작동합니다.

 

>>> m = re.search('Frank', source) >>> if m:
... print(m.group())
... 

Frank 

패턴을 변경해 보겠습니다.

>>> m = re.match('.*Frank', source) >>> if m: # match returns an object ... print(m.group()) 

... 

Young Frank 

패턴을 변경합니다.• .는 단일 문자를 의미합니다.

• *는 앞의 모든 것을 의미합니다. 합쳐서 .*는 임의의 수의 문자 행위자(심지어 0)를 의미합니다.

• Frank는 우리가 일치시키고자 했던 문구입니다. match()는 일치하는 문자열을 반환했습니다.프랭크: '젊은 프랭크'.

 

First match with search() 

검색()을 사용하여 .* 와일드카드를 사용하지 않고도 소스 문자열 'Young Frankenstein'의 아무 곳에서나 'Frank' 패턴을 찾을 수 있습니다.

 

>>> m = re.search('Frank', source) >>> if m: # search returns an object ... print(m.group())
...
Frank 

 

All matches with findall() 

위의 예들은 한 가지 일치만 찾았다. 하지만 단일 문자 문자열 'n'의 인스턴스 수를 알고 싶다면 어떻게 해야 할까요?

 

>>> m = re.findall('n', source)
>>> m # findall returns a list ['n', 'n', 'n', 'n']
>>> print('Found', len(m), 'matches') Found 4 matches 

'n' 뒤에 오는 글자는 어떤가?

    >>> m = re.findall('n.', source)

    >>> m

    ['ng', 'nk', 'ns']

 

그것이 최종 'n'과 일치하지 않는다는 것을 주목하라. 우리는 'n' 뒤에 오는 문자는 ?:의 옵션이라고 말할 필요가 있습니다.

 

  >>> m = re.findall('n.?', source)

    >>> m

    ['ng', 'nk', 'ns', 'n']

Split at matches with split() 

다음 예제에서는 일반 문자열 분할() 메서드와 같이 단순 문자열이 아닌 패턴별로 목록으로 문자열을 분할하는 방법을 보여 줍니다.

>>> m = re.split('n', source)
>>> m # split returns a list ['You', 'g Fra', 'ke', 'stei', ''] 

Patterns: special characters 

 

정규식에 대한 많은 설명은 정규식을 정의하는 방법에 대한 모든 세부 정보에서 시작됩니다. 그건 실수라고 생각해요. 정규 표현은 그 자체로 그리 작지 않은 언어이며, 여러분의 머릿속에 한번에 들어가기에는 너무 많은 세부 사항들을 가지고 있다. 그들은 너무 많은 펑크 표현을 써서 마치 만화 속 캐릭터들이 욕을 하는 것처럼 보인다.

벨트 아래에 있는 식(일치), 검색() 및 findall() 및 sub()을 사용하여 작성에 대한 세부 정보를 살펴보겠습니다. 사용자가 만든 패턴은 다음 함수에 적용됩니다.

기본 사항을 살펴보았습니다.

• 특수하지 않은 문자와 문자 그대로 일치

• 가 있는 \n을 제외한 모든 단일 문자.

• *가 포함된 임의의 숫자(0 포함)

• 선택 사항(0 또는 1)은?

 

첫째, 특수 문자는 아래에 나와 있습니다.

 

\d a single digit
\D a single non-digit
\w an alphanumeric character
\W a non-alphanumeric character
\s a whitespace character
\S a non-whitespace character
\b a word boundary (between a\wand a\W, in either order) \B a non-word boundary 

 

파이썬 문자열 모듈에는 테스트에 사용할 수 있는 미리 정의된 문자열 상수가 있습니다. 인쇄 가능한 ASCII 문자(경우, 숫자, 공백 문자, 구두점 등): 100개의 인쇄 가능한 ASCII 문자를 사용합니다.

 

>>> import string
>>> printable = string.printable
>>> len(printable)
100
>>> printable[0:50] '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN'
>>> printable[50:] 'OPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~ \t\n\r\x0b\x0c' 

 

인쇄 가능한 문자는 어떤 것입니까?

 

>>> re.findall('\d', printable) 

['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] 

 

숫자, 문자 또는 밑줄 문자는 무엇입니까?

   

>>> re.findall('\w', printable)

    ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b',

    'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',

    'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',

    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',

    'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',

    'Y', 'Z', '_']

 

공백은 무엇입니까?

 

>>> re.findall('\s', printable)
[' ', '\t', '\n', '\r', '\x0b', '\x0c'] 

 

정규식은 ASCII에만 국한되지 않습니다. \d는 단지 ASCII 문자 '0'에서 '9'까지가 아니라 유니코드가 숫자를 호출하는 것과 일치합니다. FileFormat.info에서 ASCII가 아닌 두 개의 소문자를 추가해 보겠습니다.

이 테스트에서는 다음을 포함시킵니다.

• 세 개의 ASCII 문자

• \w와 일치하지 않아야 하는 세 개의 구두점 기호

• 서클플렉스를 포함한 유니코드 라틴 소형 문자 E(\u00ea)

• BREVE가 포함된 유니코드 라틴 소형 문자 E(\u0115)

 

  • >>> x = 'abc' + '-/*' + '\u00ea' + '\u0115'

예상대로 이 패턴에는 다음과 같은 문자만 있습니다.

  •   >>> re.findall('\w', x)
  •     ['a', 'b', 'c', 'ê', 'ĕ']
  •  

Patterns: using specifiers 

이제 아래에 나와 있는 일반적인 ex press pressions의 주요 패턴 지정자를 사용하여 "punctionation pizza"를 만들어 봅시다.

표에서 expr 및 다른 기울임꼴 단어는 유효한 정규식을 의미합니다.

abc
(expr) expr1|expr2
.
^
$
prev?
prev*
prev *?
prev+
prev +? prev{m} prev{m, n} prev{m, n}? [abc] [^abc]
prev (?= next ) prev (?! next ) (?<=prev)next (?<!prev)next 

literal abc
expr
expr1
or expr2
any character except \n start of source string end of source string zero or one prev 

zero or more prev, as many as possible zero or more prev, as few as possible one or more prev, as many as possible one or more prev, as few as possible m consecutive prev 

m to n consecutive prev, as many as possible m to n consecutive prev, as few as possible aorborc(same asa|b|c)
not (aorborc) 

prev if followed by next prev if not followed by next next if preceded by prev next if not preceded by prev 

이 예들을 읽으려고 할 때 여러분의 눈은 영구적으로 교차할 수 있습니다. 먼저 소스 문자열을 정의하겠습니다.

 

    >>> source = '''I wish I may, I wish I might

    ... Have a dish of fish tonight.'''

첫째, 어디서든 소원을 찾으세요.

>>> re.findall('wish', source) 

['wish', 'wish']

다음으로, 어디에서나 소원이나 물고기를 찾으세요.

    >>> re.findall('wish|fish', source)

    ['wish', 'wish', 'fish']

시작 부분에서 소원을 찾으세요.

>>> re.findall('^wish', source) 

[] 

시작 부분에서 내 바람 찾기:

>>> re.findall('^I wish', source) 

['I wish']

마지막에 물고기 찾기:

 >>> re.findall('fish$', source)

    []

마지막에 물고기 찾기:

마지막으로, 오늘밤 물고기를 찾으세요.

>>> re.findall('fish tonight.$', source) 

    ['fish tonight.']

^ 및 $ 문자를 앵커(anchor)라고 합니다. ^ 검색의 시작 부분에 앵커(anchor)를 지정하고, $는 마침표를 포함하여 줄 끝에 있는 모든 문자와 일치하므로 효과가 있었습니다. 좀 더 정확히 말하자면, 우리는 문자 그대로 일치시키기 위해 점을 탈출해야 한다:

    >>> re.findall('fish tonight\.$', source)

    ['fish tonight.']

w 또는 f를 찾은 다음 ish를 찾습니다.

>>> re.findall('[wf]ish', source) 

['wish', 'wish', 'fish']

하나 이상의 w, s 또는 h 런을 찾습니다.

   >>> re.findall('[wsh]+', source)

    ['w', 'sh', 'w', 'sh', 'h', 'sh', 'sh', 'h']

영숫자가 아닌 ght 다음에 오는 영숫자를 찾습니다.

>>> re.findall('ght\W', source) 

['ght\n', 'ght.'] 

소원이 따라오는 것을 찾아라:

  >>> re.findall('I (?=wish)', source)

    ['I ', 'I ']

그리고 마지막으로, I 앞에 소원이 있습니다.

>>> re.findall('(?<=I) wish', source) 

    [' wish', ' wish']

정규식 패턴 규칙이 파이썬 문자열 규칙과 충돌하는 몇 가지 경우가 있습니다. 다음 패턴은 피시로 시작하는 모든 단어와 일치해야 합니다.

>>> re.findall('\bfish', source) [] 

왜 안되죠? 이전포스팅에서 논의한 바와 같이, 파이썬은 문자열에 몇 가지 특수 이스케이프 문자 액터를 사용한다. 예를 들어, \b는 문자열의 백스페이스를 의미하지만 정규식의 미니 언어에서는 단어의 시작을 의미합니다. 정규식 문자열을 정의할 때 파이썬의 원시 문자열을 사용하여 이스케이프 문자를 실수로 사용하지 않도록 합니다. 정규식 패턴 문자열 앞에 항상 r 문자를 넣으십시오. 여기서 설명한 것처럼 파이썬 이스케이프 문자를 사용할 수 없습니다.

 

   >>> re.findall(r'\bfish', source)

    ['fish']

Patterns: specifying match output 

일치() 또는 검색()을 사용하면 결과 개체 m에서 모든 일치 항목이 m.group()으로 반환됩니다. 패턴을 괄호로 묶으면 일치 항목이 해당 그룹에 저장되며, 이 중 튜플은 다음과 같이 m.group()으로 사용할 수 있습니다.

    >>> m = re.search(r'(. dish\b).*(\bfish)', source)

    >>> m.group()

    'a dish of fish'

    >>> m.groups()

('a dish', 'fish')

이 패턴을 사용하면(?)P<name>expr), 일치 항목을 그룹에 저장합니다.

이름:

  >>> m = re.search(r'(?P<DISH>. dish\b).*(?P<FISH>\bfish)', source)

    >>> m.group()

    'a dish of fish'

    >>> m.groups()

    ('a dish', 'fish')

    >>> m.group('DISH')

    'a dish'

    >>> m.group('FISH')

    'fish'

bytes and bytearray 

파이썬 3은 다음과 같은 8비트 정수 시퀀스를 도입했으며, 0부터 255까지의 값을 두 가지 유형으로 사용할 수 있다.

• 바이트는 불변입니다. 바이트 튜플처럼 • 바이트 목록처럼 bytray는 변경할 수 있습니다.

블리스트라는 목록으로 시작하여 다음 예제는 바이트 변수인 바이트 변수와 바이트_array라는 바이어레이 변수를 생성합니다.

>> blist = [1, 2, 3, 255]
>>> the_bytes = bytes(blist)
>>> the_bytes
b'\x01\x02\x03\xff'
>>> the_byte_array = bytearray(blist) >>> the_byte_array bytearray(b'\x01\x02\x03\xff') 

바이트 값의 표현은 b와 따옴표 문자 다음에 \x02 또는 ASCII charac sequences ters와 같은 16진수 시퀀스로 시작하고 일치하는 따옴표 문자로 끝납니다. 파이썬은 16진수 시퀀스 또는 ASCII 문자를 작은 정수로 변환하지만 유효한 ASCII 인코딩인 바이트 값을 ASCII 문자로 표시합니다.

>>> b'\x61' b'a' 

>>> b'\x01abc\xff' b'\x01abc\xff' 

다음 예에서는 바이트 변수를 변경할 수 없음을 보여줍니다.

    >>> the_bytes[1] = 127

    Traceback (most recent call last):

File "<stdin>", line 1, in <module>
TypeError: 'bytes' object does not support item assignment 

그러나 곁눈질 변수는 부드럽고 변이성이 있습니다.

>>> the_byte_array = bytearray(blist) >>> the_byte_array bytearray(b'\x01\x02\x03\xff')
>>> the_byte_array[1] = 127 

>>> the_byte_array bytearray(b'\x01\x7f\x03\xff') 

 

각 값은 0에서 255 사이의 값을 갖는 256 요소 결과를 생성합니다.

 

   >>> the_bytes = bytes(range(0, 256))

    >>> the_byte_array = bytearray(range(0, 256))

 

바이트 또는 byterray 데이터를 인쇄할 때 Python은 인쇄할 수 없는 바이트에 \x x를 사용하고 인쇄 가능한 바이트에 ASCII 등가(및 \x0a 대신 \n과 같은 일반적인 이스케이프 문자)를 사용합니다. 다음은_bytes의 인쇄된 표현입니다(한 줄당 16바이트를 표시하도록 수동 참조).

 

>>> the_bytes b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f \x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&\'()*+,-./
0123456789:;<=>?
@ABCDEFGHIJKLMNO
PQRSTUVWXYZ[\\]^_
`abcdefghijklmno
pqrstuvwxyz{|}~\x7f \x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f \x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f \xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf \xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf \xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf \xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf \xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef \xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff' 

문자가 아닌 바이트(10개의 정수)이기 때문에 헷갈릴 수 있습니다.

 

해야 할 일

7.1. mystery라는 유니코드 문자열을 만들고 값을 '\U0001f4a9'로 지정합니다. 미스테리를 인쇄하다. 유니코드 이름을 찾아보십시오.

 

7.2. 이번에는 UTF-8을 사용하여 미스터리를 바이트 변수 pop_bytes로 인코딩합니다. pop_bytes를 인쇄합니다.

 

7.3. UTF-8을 사용하여 pop_bytes를 문자열 변수 pop_string으로 디코딩한다. pop_string을 인쇄합니다. 팝 스트링이 미스터리와 같은가?

 

7.4. 다음 시를 구식으로 쓰세요. 'roast beef', 'ham', 'head' 및 'clam' 문자열을 다음 문자열로 대체하십시오.

 

My kitty cat likes %s,

My kitty cat likes %s,

My kitty cat fell on his %s

And now thinks he's a %s.

 

7.5. 새로운 서식을 사용해서 양식 편지를 쓰세요. 다음 문자열을 문자로 저장합니다(다음 연습에서 사용합니다).

 

Dear {salutation} {name},

Thank you for your letter. We are sorry that our {product} {verbed} in your

{room}. Please note that it should never be used in a {room}, especially

near any {animals}.

Send us your receipt and {amount} for shipping and handling. We will send

you another {product} that, in our tests, is {percent}% less likely to

have {verbed}.

Thank you for your support.

Sincerely,

{spokesman}

 {job_title}

 

7.6. 문자열 키 'salutation', 'name', 'product', 'verbed'(과거 시제 동사), 'room', 'animals', '양', 'per cent', 'spokesman', 'job_title'의 값을 가진 response라는 사전을 만드십시오. 반응 값이 포함된 문자를 인쇄합니다.

 

7.7. 텍스트 작업을 할 때 정규 표현식이 매우 유용합니다. 여러 가지 방법으로 특집 텍스트 샘플에 적용할 것입니다. 이 시는 1866년 제임스 맥킨타이어가 온타리오에서 만들어 국제 순회공연을 위해 보낸 7천 파운드짜리 치즈에 경의를 표하기 위해 쓴 "매머드 치즈 송가"라는 제목의 시입니다. 모든 것을 입력하지 않으려면, 좋아하는 검색 엔진을 사용하여 단어를 잘라내어 파이썬 프로그램에 붙여 넣으십시오. 아니면, 프로젝트 구텐베르크에서 가져와요. 텍스트 문자열을 매머드라고 합니다.

 

    We have seen thee, queen of cheese,

    Lying quietly at your ease,

    Gently fanned by evening breeze,

    Thy fair form no flies dare seize.

    All gaily dressed soon you'll go

    To the great Provincial show,

    To be admired by many a beau

    In the city of Toronto.

    Cows numerous as a swarm of bees,

    Or as the leaves upon the trees,

    It did require to make thee please,

    And stand unrivalled, queen of cheese.

    May you not receive a scar as

    We have heard that Mr. Harris

    Intends to send you off as far as

    The great world's show at Paris.

    Of the youth beware of these,

    For some of them might rudely squeeze

    And bite your cheek, then songs or glees

    We could not sing, oh! queen of cheese.

    We'rt thou suspended from balloon,

    You'd cast a shade even at noon,

    Folks would think it was the moon

    About to fall and crush them soon.

 

7.8. 파이썬의 정규식 함수를 사용하려면 re 모듈을 가져옵니다. re.findall()을 사용하여 c로 시작하는 모든 단어를 인쇄합니다.

 

7.9. c로 시작하는 4글자를 모두 찾아라.

 

7.10. r로 끝나는 모든 단어를 찾아라.

 

7.11. 정확히 세 개의 모음을 연속으로 포함하는 모든 단어들을 찾아라.

 

7.12. unexlify를 사용하여 이 16진수 문자열(페이지에 맞도록 두 개의 문자열에서 조합됨)을 gif라는 바이트 변수로 변환합니다.

 

  '47494638396101000100800000000000ffffff21f9' +

    '0401000000002c000000000100010000020144003b'

파이썬코드 Mangle Data Like a Pro

이번 포스팅에서는 데이터 길들이기 위한 여러 가지 기술에 대해 알아봅니다. 이들 대부분은 다음과 같은 내장 파이썬 데이터 유형에 관한 것이다.

줄들

텍스트 데이터에 사용되는 유니코드 문자 시퀀스.

바이트와 바이패스

이진 데이터에 사용되는 8비트 정수 시퀀스입니다.

텍스트 문자열

텍스트는 대부분의 독자들에게 가장 익숙한 데이터 유형입니다. 따라서 파이썬에서 텍스트 문자열의 강력한 기능 중 몇 가지를 살펴보겠습니다.

유니코드

지금까지 이 책의 모든 텍스트 예제는 평범한 옛 아스키이다. ASCII는 1960년대에 정의되었는데, 그 당시 컴퓨터는 냉장고 크기였고 계산을 조금 더 잘했다. 컴퓨터 저장의 기본 단위는 바이트이며, 바이트는 8비트에 256개의 고유값을 저장할 수 있다. 여러 가지 이유로 ASCII는 대문자 26개, 소문자 26개, 숫자 10개, 일부 펑크음 기호, 일부 띄어쓰기 문자 및 일부 비인쇄 제어 코드 등 7비트(128개의 고유 값)만 사용했습니다.

불행하게도, 세계는 ASCII가 제공하는 것보다 더 많은 글자를 가지고 있다. 당신은 식당에서 핫도그를 먹을 수 있지만, 카페에서는 절대로 게뷔르츠트라미네르1을 먹지 않는다. 더 많은 문자와 기호를 추가하기 위한 많은 시도가 있었고, 여러분은 때때로 그것들을 볼 수 있을 것입니다. 그 중 몇 가지 예를 들 수 있습니다.

 

1. 이 와인은 독일에 음라우트가 있는데 프랑스에서는 잃어버려요.

Latin-1, or ISO 8859-1
• Windows code page 1252 

이들 각각은 8비트를 모두 사용합니다. 하지만 그것조차도 충분하지 않습니다. 특히 비유럽 언어가 필요할 때는요. 유니코드는 수학과 다른 분야의 기호와 더불어 세계 모든 언어의 문자를 정의하는 지속적인 국제 표준이다.

유니코드는 플랫폼, 프로그램, 언어와 상관없이 모든 문자에 대해 고유한 번호를 제공합니다.

 

유니코드 코드 차트 페이지에는 이미지가 있는 현재 정의된 모든 문자 집합에 대한 링크가 있습니다. 최신 버전(6.2)에서는 각각 고유한 이름과 식별 번호를 가진 110,000자 이상의 문자를 정의합니다. 문자는 평면이라고 하는 8비트 집합으로 나뉩니다. 처음 256면은 기본 다국어 평면이다. 자세한 내용은 유니코드 평면에 대한 위키피디아 페이지를 참조하십시오.

 

파이썬 3 유니코드 문자열

Python 3 문자열은 바이트 배열이 아닌 유니코드 문자열입니다. 이는 일반 바이트 문자열과 유니코드 문자 문자열을 구분하는 파이썬 2와 비교할 때 가장 큰 변화입니다.

 

유니코드 ID 또는 문자 이름을 알고 있는 경우 파이썬 문자열에서 사용할 수 있습니다. 다음은 몇 가지 예입니다.

 

• \u 다음에 4개의 16진수2는 유니코드의 256개의 기본 다국어 평면 중 하나에 있는 문자를 지정합니다. 처음 두 개는 평면 번호(00에서 FF)이고 다음 두 개는 평면 내 문자 색인입니다. 평면 00은 오래된 ASCII이며, 평면 내의 문자 위치는 ASCII와 동일합니다.

 

• 고차원 문자의 경우 비트가 더 필요합니다. Python 이스케이프 시퀀스는 \U 다음에 8개의 16진수 문자가 나옵니다. 가장 왼쪽 문자는 0이어야 합니다.

 

• 모든 문자에 대해 \N{ 이름 }을(를) 사용하여 표준 이름으로 지정할 수 있습니다. 유니코드 문자 이름 색인 페이지에는 이러한 항목이 나열됩니다.

파이썬 유니코드다 모듈에는 양방향으로 변환하는 기능이 있습니다.

 

• 검색—대소문자를 구분하지 않는 이름을 사용하고 유니코드 문자를 반환합니다.

 

• 이름 표시—유니코드 문자를 사용하고 대문자 이름을 반환합니다.

 

다음 예에서는 Python Unicode char act acter를 사용하여 이름을 조회한 다음 이름(원래 문자와 일치해야 함)에서 문자를 다시 검색하는 테스트 함수를 작성하겠습니다.

 

>>> def unicode_test(value): 

  • ...  import unicodedata
  •     ...      name = unicodedata.name(value)
  •  
  •     ...      value2 = unicodedata.lookup(name)
  •  
  • ...  print('value="%s", name="%s", value2="%s"' % (value, name, value2)) ...

일반 ASCII 문자로 시작하는 몇 가지 문자를 사용해 보겠습니다.

 

  • >>> unicode_test('A')
  •     value="A", name="LATIN CAPITAL LETTER A", value2="A"

  • ASCII punctuation:
        >>> unicode_test('$')
  •     value="$", name="DOLLAR SIGN", value2="$"

  • A Unicode currency character:
    >>> unicode_test('\u00a2')
    value="¢", name="CENT SIGN", value2="¢"
    Another Unicode currency character:
    >>> unicode_test('\u20ac')
    value="€", name="EURO SIGN", value2="€"

잠재적으로 발생할 수 있는 유일한 문제는 텍스트를 표시하는 데 사용하는 글꼴의 제한입니다. 모든 글꼴에 모든 유니코드 문자에 대한 이미지가 없는 경우 일부 자리 표시자 문자가 표시될 수 있습니다. 예를 들어, 딩뱃 글꼴의 기호와 같은 스노우맨의 유니코드 기호는 다음과 같습니다.

 

  • >>> unicode_test('\u2603')
    value="☃", name="SNOWMAN", value2="☃"

카페라는 단어를 파이썬 문자열에 저장하려고 합니다. 한 가지 방법은 파일이나 웹 사이트에서 복사하여 붙여넣기하여 다음 작업을 수행하는 것입니다.

 

  •   >>> place = 'café'
  •     >>> place
  •     'café'
  •  

UTF-8 인코딩을 사용한 원본에서 텍스트에 복사하여 붙여넣었기 때문에 가능했습니다.

최종문자를 어떻게 지정할 수 있습니까? E의 문자 색인을 보면, 급성 라틴 소문자 이름 E의 값이 00E9임을 알 수 있습니다. 방금 사용하던 이름() 및 조회() 함수로 확인해 보겠습니다. 먼저 코드를 입력하여 이름을 가져옵니다.

 

>>> unicodedata.name('\u00e9') 'LATIN SMALL LETTER E WITH ACUTE' 

그런 다음 코드를 조회할 이름을 지정합니다.

 >>> unicodedata.lookup('E WITH ACUTE, LATIN SMALL LETTER')

    Traceback (most recent call last):

File "<stdin>", line 1, in <module>
KeyError: "undefined character name 'E WITH ACUTE, LATIN SMALL LETTER'" 

유니코드 문자 이름 색인 페이지에 나열된 이름은 표시에 적합하게 정렬되도록 다시 포맷되었습니다. 이러한 이름을 실제 유니코드 이름(파이썬에서 사용하는 이름)으로 변환하려면 쉼표를 제거하고 쉼표 뒤에 있던 이름의 일부를 처음으로 이동합니다. 따라서 급성 라틴 소문자 E를 급성 라틴 소문자 E로 변경합니다.

 

>>> unicodedata.lookup('LATIN SMALL LETTER E WITH ACUTE') 'é' 

이제 코드 또는 이름으로 문자열 카페를 지정할 수 있습니다.

>>> place = 'caf\u00e9'
>>> place
'café'
>>> place = 'caf\N{LATIN SMALL LETTER E WITH ACUTE}' >>> place 

'café' 

앞의 코드 조각에서 문자열에 직접 é를 삽입했지만 다음을 추가하여 문자열을 만들 수도 있습니다.

 

>>> u_umlaut = '\N{LATIN SMALL LETTER U WITH DIAERESIS}' >>> u_umlaut
'ü'
>>> drink = 'Gew' + u_umlaut + 'rztraminer' 

>>> print('Now I can finally have my', drink, 'in a', place) Now I can finally have my Gewürztraminer in a café 

문자열 렌 함수는 바이트가 아닌 유니코드 문자를 카운트합니다.

>>> len('$')
1
>>> len('\U0001f47b') 1 

Encode and decode with UTF-8 

일반적인 문자열을 처리할 때 파이썬에서 각 유니코드 문자를 저장하는 방법에 대해 걱정할 필요가 없습니다.

그러나 외부와 데이터를 교환할 때는 두 가지 사항이 필요합니다.

 

문자 문자열을 바이트로 인코딩하는 방법

문자 문자열로 바이트를 디코딩하는 방법

 

유니코드에 64,000자 미만의 문자가 있으면 각 유니코드 문자 ID를 2바이트로 저장할 수 있습니다. 불행하게도, 더 있습니다. 각 ID를 3, 4바이트 단위로 인코딩할 수 있지만, 그렇게 하면 공통 텍스트 문자열에 대한 메모리 및 디스크 저장 공간이 3, 4배 증가합니다.

Unix 개발자들에게 친숙한 이름을 가진 Ken Thompson과 Rob Pike는 어느 날 밤 뉴저지의 한 식당에서 UTF-8 동적 인코딩 방식에 서명했다. 유니코드 문자당 1~4바이트를 사용합니다.

 

• ASC용 1바이트Ⅱ

• 대부분의 라틴어에서 파생된 언어(키릴어는 아님)의 경우 2바이트

• 나머지 다국어 평면의 경우 3바이트

• 일부 아시아 언어와 기호를 포함한 나머지 4바이트

 

UTF-8은 Python, Linux 및 HTML의 표준 텍스트 인코딩입니다. 빠르고 완전하며 잘 작동합니다. 만약 당신이 코드 전체에 UTF-8 인코딩을 사용한다면, 삶은 다양한 인코딩에 들어가고 나오는 것보다 훨씬 쉬울 것이다.

 

웹 페이지와 같은 다른 원본에서 복사하여 붙여넣기하여 파이썬 문자열을 만드는 경우, 소스가 UTF-8 형식으로 인코딩되어 있는지 확인하십시오. Latin-1 또는 Windows 1252로 인코딩된 텍스트가 파이썬 문자열로 복사되어 나중에 잘못된 바이트 시퀀스로 돌출되는 것을 볼 수 있습니다.

 

  • Encoding 
  • 문자열을 바이트로 인코딩합니다. 문자열 인코딩() 함수의 첫 번째 인수는 en coding 부호화 이름입니다. 선택사항은 표 7-1에 제시된 것을 포함한다.
  • Table 7-1. Encodings 
  • 'ascii' Good old seven-bit ASCII
    'utf-8' Eight-bit variable-length encoding, and what you almost always want to use 
  • 'latin-1' Also known as ISO 8859-1
    'cp-1252' A common Windows encoding
  • 'unicode-escape' Python Unicode literal format,\uxxxx or\Uxxxxxxxx 

 

  • UTF-8로 인코딩할 수 있습니다. 유니코드 문자열 '\u2603'을 스노우맨 이름에 할당해 보겠습니다.

>>> snowman = '\u2603' 

스노우맨은 내부적으로 저장하는 데 필요한 바이트 수에 관계없이 단일 문자를 가진 파이썬 유니코드 문자열입니다.

 

 >>> len(snowman)

    1

다음으로 이 유니코드 문자를 바이트 순서로 인코딩해 보겠습니다.

>>> ds = snowman.encode('utf-8')

앞서 언급했듯이 UTF-8은 가변 길이 인코딩입니다. 이 경우, 3개를 사용했습니다.

단일 눈사람 유니코드 문자를 인코딩하는 바이트:

 

>>> len(ds)
3
>>> ds b'\xe2\x98\x83' 

이제 len()은 ds가 바이트 변수이기 때문에 바이트 수를 반환합니다.

UTF-8 이외의 인코딩을 사용할 수 있지만 인코딩으로 유니코드 문자열을 처리할 수 없는 경우 오류가 발생합니다. 예를 들어, ASCII 인코딩을 사용하는 경우 유니코드 문자도 유효한 ASCII 문자가 아니면 실패합니다.

  >>> ds = snowman.encode('ascii')

    Traceback (most recent call last):

File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u2603' in position 0: ordinal not in range(128) 

인코딩() 함수는 인코딩 예외를 방지하는 데 도움이 되는 두 번째 인수를 사용합니다. 이전 예에서 볼 수 있는 기본값은 '엄격'입니다. ASC가 아닌 경우 유니코드EncodeError가 발생합니다.II 캐릭터. 다른 인코딩도 있습니다. 인코딩되지 않는 것을 버리려면 '무시'를 사용하십시오.

 

  >>> snowman.encode('ascii', 'ignore')

    b''

알 수 없는 문자를 대체하려면 '바꾸기'를 사용하십시오.

>>> snowman.encode('ascii', 'replace') 

b'?'

유니코드와 같은 파이썬 유니코드 문자 문자열을 만들려면 '백슬래시 바꾸기'를 사용하십시오.

escape:
>>> snowman.encode('ascii', 'backslashreplace') 

b'\\u2603'

유니코드 이스케이프 시퀀스의 인쇄 가능한 버전이 필요한 경우 이 옵션을 사용합니다. 다음은 웹 페이지에서 사용할 수 있는 문자 엔터티 문자열을 생성합니다.

 

 >>> snowman.encode('ascii', 'xmlcharrefreplace')

    b'&#9731;'

 

디코딩

바이트 문자열을 유니코드 문자열로 디코딩합니다. 일부 외부 소스(파일, 데이터베이스, 웹 사이트, 네트워크 API 등)에서 텍스트를 가져올 때마다 바이트 문자열로 인코딩됩니다. 까다로운 부분은 어떤 인코딩이 실제로 사용되었는지 알기 때문에 이를 역방향으로 실행하고 유니코드 문자열을 가져올 수 있습니다.

문제는 바이트 문자열 자체에 사용된 인코딩을 나타내는 것은 없다는 것이다. 나는 앞서 웹사이트에서 복사와 붙여넣기의 위험에 대해 언급했다. 여러분은 아마도 보통 오래된 ASCII 문자가 있어야 하는 홀수 문자로 웹사이트를 방문한 적이 있을 것이다.

'카페' 값을 사용하여 플레이스라는 유니코드 문자열을 만듭니다.

 

>>> place = 'caf\u00e9' >>> place
'café'
>>> type(place) 

<class 'str'>

place_bytes라는 바이트 변수로 UTF-8 형식으로 인코딩합니다.

 

>>> place_bytes = place.encode('utf-8') >>> place_bytes
b'caf\xc3\xa9'
>>> type(place_bytes) 

<class 'bytes'> 

place_bytes는 5바이트입니다. 처음 3개는 ASCII (UTF-8의 강도)와 동일하며, 마지막 2개는 'é'를 인코딩한다. 이제 바이트 문자열을 유니코드 문자열로 다시 디코딩해 보겠습니다.

 

 >>> place2 = place_bytes.decode('utf-8')

    >>> place2

    'café'

UTF-8로 인코딩하고 UTF-8로 디코딩했기 때문에 가능했습니다. 다른 인코딩에서 디코딩하라고 하면 어떨까요?

 

 >>> place3 = place_bytes.decode('ascii')

    Traceback (most recent call last):

File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 3: ordinal not in range(128) 

바이트 값 0xc3이 ASCII에서 잘못되었기 때문에 ASCII 디코더가 예외를 발생시켰습니다. 128 (헥스 80)과 255 (헥스 FF) 사이의 값이 UTF-8과 동일하지는 않지만 합법적인 일부 8비트 문자 집합 인코딩이 있습니다.

 

  >>> place4 = place_bytes.decode('latin-1')

    >>> place4

    'café'

    >>> place5 = place_bytes.decode('windows-1252')

    >>> place5

    'café'

 

Urk. 

이 이야기의 교훈은 가능할 때마다 UTF-8 인코딩을 사용하라는 것이다. 모든 곳에서 작동하고 지원되며 모든 유니코드 문자를 표현할 수 있으며 빠르게 디코딩되고 인코딩됩니다.

 

이 이야기의 교훈은 가능할 때마다 UTF-8 인코딩을 사용하라는 것이다. 모든 곳에서 작동하고 지원되며 모든 유니코드 문자를 표현할 수 있으며 빠르게 디코딩되고 인코딩됩니다.

자세한 정보는

자세한 내용은 다음 링크를 참조하십시오.

 

• 유니코드 HOWTO

• 실용 유니코드

모든 소프트웨어 개발자가 유니코드 문자 집합에 대해 절대적으로 알아야 하는 절대 최소값(변명 없음

파이상자 Handle Missing Keys with setdefault() and defaultdict()

Handle Missing Keys with setdefault() and defaultdict() 

존재하지 않는 키로 사전에 액세스하려고 하면 탁월한 효과를 얻을 수 있습니다. 사전 get() 함수를 사용하여 기본값을 반환하면 예외가 발생하지 않습니다.

setdefault() 함수는 get()와 같지만 키가 없는 경우 사전에 항목을 할당합니다.

 

>>> periodic_table = {'Hydrogen': 1, 'Helium': 2} >>> print(periodic_table)
{'Helium': 2, 'Hydrogen': 1} 

 

키가 사전에 없는 경우 새 값이 사용됩니다.

 

 >>> carbon = periodic_table.setdefault('Carbon', 12)

    >>> carbon

    12

    >>> periodic_table

{'Helium': 2, 'Carbon': 12, 'Hydrogen': 1}

기존 키에 다른 기본값을 할당하려고 하면 원래 값이 반환됩니다.

아무것도 변경되지 않습니다.

 

  >>> helium = periodic_table.setdefault('Helium', 947)

    >>> helium

    2

    >>> periodic_table

    {'Helium': 2, 'Carbon': 12, 'Hydrogen': 1}

 

defaultdict()도 비슷하지만 사전을 만들 때 앞에 있는 모든 새 키의 기본값을 지정합니다. 인수는 함수입니다. 이 예에서는 int()라고 하는 함수 int를 전달하고 정수 0을 반환합니다.

 

>>> from collections import defaultdict >>> periodic_table = defaultdict(int) 

 

이제 결측값은 정수(int)이며 값은 0입니다.

>>> periodic_table['Hydrogen'] = 1
>>> periodic_table['Lead']
0
>>> periodic_table
defaultdict(<class 'int'>, {'Lead': 0, 'Hydrogen': 1}) 

defaultdict() 인수는 누락된 키에 할당할 값을 반환하는 함수입니다. 다음 예에서 no_idea()는 필요할 때 값을 반환하기 위해 실행됩니다.

 

>>> from collections import defaultdict >>>
>>> def no_idea():
... return 'Huh?' 

    ...

    >>> bestiary = defaultdict(no_idea)

    >>> bestiary['A'] = 'Abominable Snowman'

    >>> bestiary['B'] = 'Basilisk'

    >>> bestiary['A']

    'Abominable Snowman'

    >>> bestiary['B']

 'Basilisk'

    >>> bestiary['C']

    'Huh?'

 

int() 함수, list() 함수 또는 dict() 함수를 사용하여 해당 유형의 기본 빈 값을 반환할 수 있습니다. int()는 0을 반환하고 list()는 빈 목록([])을 반환하며 dict()는 빈 사전({})을 반환합니다. 인수를 생략하면 새 키의 초기 값이 없음으로 설정됩니다.

그런데 통화 내에서 람다를 사용하여 기본 설정 함수를 정의할 수 있습니다.

 >>> bestiary = defaultdict(lambda: 'Huh?') >>> bestiary['E']
'Huh?' 

int를 사용하는 것도 자신만의 카운터를 만드는 한 가지 방법입니다.

 

>>> from collections import defaultdict
>>> food_counter = defaultdict(int)
>>> for food in ['spam', 'spam', 'eggs', 'spam']: ... food_counter[food] += 1
...
>>> for food, count in food_counter.items():
... print(food, count)
...
eggs 1
spam 3 

 

앞의 예에서, food_counter가 디폴트딕트 대신 일반 사전이었다면, 파이썬은 초기화되지 않았기 때문에 food_counter[food] 사전 요소를 증가시키려고 할 때마다 예외를 제기했을 것이다. 여기에 표시된 것처럼 추가 작업이 필요했을 것입니다.

 

>>> dict_counter = {}
>>> for food in ['spam', 'spam', 'eggs', 'spam']: 

...
>>> for food, count in dict_counter.items(): ... print(food, count) 

... 

spam 3 eggs 1 

Count Items with Counter() 

카운터 얘기가 나와서 말인데, 표준 라이브러리에는 이전 예제와 같은 작업을 수행하는 라이브러리가 있습니다.

 

>>> from collections import Counter
>>> breakfast = ['spam', 'spam', 'eggs', 'spam'] >>> breakfast_counter = Counter(breakfast)
>>> breakfast_counter
Counter({'spam': 3, 'eggs': 1}) 

most_common() 함수는 모든 요소를 내림차순으로 반환하거나 카운트가 주어진 경우 최상위 카운트 요소만 반환합니다.

 

 >>> breakfast_counter.most_common()

    [('spam', 3), ('eggs', 1)]

    >>> breakfast_counter.most_common(1)

    [('spam', 3)]

 

카운터를 결합할 수 있습니다. 먼저, breakfast_counter에 무엇이 있는지 다시 한 번 살펴보겠습니다.

 

>>> breakfast_counter 

>>> Counter({'spam': 3, 'eggs': 1})

이번에는 점심이라고 불리는 새로운 목록과 점심 카운터라고 불리는 카운터를 만들겠습니다.

 

 >>> lunch = ['eggs', 'eggs', 'bacon']

    >>> lunch_counter = Counter(lunch)

    >>> lunch_counter

    Counter({'eggs': 2, 'bacon': 1})

 

두 카운터를 결합하는 첫 번째 방법은 +를 사용하는 덧셈입니다.

 

>>> breakfast_counter + lunch_counter 

Counter({'spam': 3, 'eggs': 3, 'bacon': 1})

예상하신 대로 -를 사용하여 카운터 하나를 다른 카운터에서 뺍니다.

아침은 안먹고 점심은 안먹어?

 

>>> breakfast_counter - lunch_counter

    Counter({'spam': 3})

좋아요, 그럼 아침으로 먹을 수 없는 점심으로 뭘 먹을 수 있을까요?

 

  >>> lunch_counter - breakfast_counter

    Counter({'bacon': 1, 'eggs': 1})

 

이전의 세트와 마찬가지로 교차로 op‐ erator &:를 사용하여 공통 항목을 얻을 수 있습니다.

 >>> breakfast_counter & lunch_counter

    Counter({'eggs': 1})

교차로는 공통 요소(계란)를 더 낮은 수로 선택했습니다. 이것은 말이 된다: 아침식사는 계란 한 개만 제공했기 때문에, 그것이 일반적인 계산이다.

마지막으로, 유니언 연산자를 사용하여 모든 항목을 가져올 수 있습니다. |:

 

 >>> breakfast_counter | lunch_counter

    Counter({'spam': 3, 'eggs': 2, 'bacon': 1})

 

'계란'이라는 항목은 다시 두 가지 모두에 공통적이었다. 조합은 덧셈과 달리 인원수를 늘리지 않고 더 큰 숫자를 골랐다.

 

Order by Key with OrderedDict() 

이 책의 초기 장에 있는 많은 코드 예제는 사전의 키 순서를 예측할 수 없다는 것을 보여준다. 키 a, b 및 c는 해당 순서로 추가할 수 있지만 키()는 c, a, b를 반환할 수 있다. 여기 이전포스팅에서 용도를 변경한 예가 있습니다.

 

>>> quotes = { 

  •     ...      'Moe': 'A wise guy, huh?',
  •  
  •     ...      'Larry': 'Ow!',
  •  
  • ...  'Curly': 'Nyuk nyuk!', ... }
    >>> for stooge in quotes:
    ... print(stooge)
    ...
    Larry
    Curly
    Moe

OrderedDict()는 키 추가 순서를 기억하고 반복자로부터 동일한 순서로 반환합니다. (키, 값) 튜플 순서에서 OrderedDict를 만들어 보십시오.

 

  • >>> from collections import OrderedDict >>> quotes = OrderedDict([
  • Stack + Queue == deque

데크(데크 발음)는 스택과 큐의 기능을 모두 갖춘 이중 종단 큐입니다. 시퀀스의 양쪽 끝에서 항목을 추가 및 삭제할 때 유용합니다. 여기, 우리는 단어 양쪽 끝에서 중간까지 페일린 드롬인지 알아봅니다. popleft() 함수는 데크에서 맨 왼쪽 항목을 제거했다가 반환합니다. pop()은 맨 오른쪽 항목을 제거했다가 반환합니다. 함께, 그들은 끝에서 중간까지 일을 합니다. 끝 문자가 일치하는 한 중간에 도달할 때까지 계속 터집니다.

 

>>> def palindrome(word): 

...

>>> palindrome('a')

True

from collections import deque dq = deque(word)
while len(dq) > 1: 

if dq.popleft() != dq.pop(): return False 

return True 

    >>> palindrome('racecar')

    True

    >>> palindrome('')

    True

    >>> palindrome('radar')

    True

    >>> palindrome('halibut')

    False

 

저는 이것을 단순한 데크의 삽화로 사용했습니다. 만약 당신이 빠른 회문 체커를 원한다면, 단지 문자열을 그것의 반대와 비교하는 것이 훨씬 더 간단할 것이다. Python에는 문자열에 대한 역함수가 없지만 여기에 표시된 것처럼 슬라이스로 문자열을 역방향으로 사용할 수 있는 방법이 있습니다.

 

>>> def another_palindrome(word): ... return word == word[::-1] ...
>>> another_palindrome('radar') True 

    >>> another_palindrome('halibut')

    False

 

Iterate over Code Structures with itertools 

이터툴스는 특수 목적 반복기 기능을 포함한다. 각각 ...에 대해 a 내에서 호출하면 한 번에 하나의 항목을 반환합니다. 호출 사이의 상태를 기억합니다.

chain은 마치 하나의 참을 수 있는 것처럼 그 논거를 통과한다.

 

>>> import itertools
>>> for item in itertools.chain([1, 2], ['a', 'b']): ... print(item)
...
1
2
a
b 

cycle()은 무한 반복자로, 그 인수를 순환한다.

>>> import itertools
>>> for item in itertools.cycle([1, 2]): ... print(item)
...
1
2
1
2
.
.
. 

기타 등등.

누적은 누적된 값을 계산합니다. 기본적으로 합계가 계산됩니다.

>>> import itertools
>>> for item in itertools.accumulate([1, 2, 3, 4]): ... print(item)
...
1
3
6
10 

누적()할 두 번째 인수로 함수를 제공할 수 있으며, 추가 대신 이 인수가 사용됩니다. 함수는 두 개의 인수를 사용하여 단일 결과를 반환해야 합니다. 이 예제에서는 누적 제품을 계산합니다.

>>> import itertools
>>> def multiply(a, b):
... returna*b
...
>>> for item in itertools.accumulate([1, 2, 3, 4], multiply): ... print(item)
...
1
2
6
24 

이터툴즈 모듈에는 더 많은 기능이 있으며, 특히 필요에 따라 시간을 절약할 수 있는 조합과 순열에 대한 기능이 있습니다.

 

Print Nicely with pprint() 

모든 예제는 인쇄()(또는 대화형 인터프리터의 변수 이름만)를 사용하여 인쇄했습니다. 때때로, 그 결과는 읽기 어렵다. 우리는 print 와 같은 예쁜 프린터가 필요하다.

 

>>> from pprint import pprint >>> quotes = OrderedDict([ 

  • ...      ('Moe', 'A wise guy, huh?'),
  •  
  •     ...      ('Larry', 'Ow!'),
  •  
  •     ...      ('Curly', 'Nyuk nyuk!'),
  •     ...     ])

  • >>>

그냥 오래된 인쇄물은 물건들을 그냥 저기에 버립니다.

 

  • >>> print(quotes)
    OrderedDict([('Moe', 'A wise guy, huh?'), ('Larry', 'Ow!'), ('Curly', 'Nyuk nyuk!')]) 

그러나 pprint()는 가독성을 높이기 위해 요소를 정렬하려고 합니다.

 

  •     >>> pprint(quotes)
  •     {'Moe': 'A wise guy, huh?',
  •   'Larry': 'Ow!',
  •     'Curly': 'Nyuk nyuk!'}

More Batteries: Get Other Python Code 

때때로, 표준 라이브러리는 여러분이 필요로 하는 것을 가지고 있지 않거나, 아주 올바른 방법으로 그것을 하지 않습니다. 오픈 소스, 타사 파이썬 소프트웨어가 전 세계에 걸쳐 있습니다. 좋은 리소스는 다음과 같습니다.

  • • PyPi (also known as the Cheese Shop, after an old Monty Python skit)
  • • github
  • • readthedocs

activestate에서 더 작은 코드 예제를 많이 볼 수 있습니다.

 

이 책에 있는 거의 모든 파이썬 코드는 모든 내장 및 표준 라이브러리를 포함하는 컴퓨터에 표준 파이썬 설치를 사용합니다. 외부 패키지는 다음과 같은 위치에 있습니다. 1장에서 요청을 언급했으며, 222페이지의 "표준 라이브러리 너머: 요청"에서 자세한 내용을 설명합니다. 부록 D는 다른 많은 너트 앤 볼트 개발 세부사항과 함께 타사 파이썬 소프트웨어를 설치하는 방법을 보여준다.

 

해야 할 일

5.1. zoo.py이라는 파일을 만듭니다. 여기에서 '매일 9-5 열기' 문자열을 인쇄하는 hours()라는 함수를 정의합니다. 그런 다음 대화형 통역기를 사용하여 동물원 모듈을 가져오고 시간() 기능을 호출합니다.

5.2. 대화형 통역기에서 동물원 모듈을 menagerie로 가져오고 시간() 기능을 호출한다.

5.3. 통역실에 머무르면서 동물원으로부터 직접 시간() 기능을 가져와 전화한다.

5.4. 시간() 기능을 정보로 가져와 호출합니다.

5.5. 키-값 쌍 'a'가 1, 'b': 2, 'c'인 일반 사전을 만듭니다.

3번, 그리고 인쇄하세요.

5.6. 5.5에 나열된 동일한 쌍으로 팬시라고 불리는 OrderedDict를 만들어 인쇄합니다.

일반과 같은 순서로 인쇄되었습니까?

5.7. dict_of_lists라는 디폴트딕트를 만들어 인수 목록을 전달합니다. 목록을 dict_of_lists['a'] 만들고 번의 할당으로 'something for a' 값을 추가합니다. dict_of_lists['a'] 인쇄합니다.

파이 상자: 모듈, 패키지 및 프로그램

상향식 상향식 상향식에서는 내장 데이터 유형에서 점점 더 큰 데이터 및 코드 구조를 구축하는 방식으로 발전해 왔습니다. 이 챕터에서는 마지막으로 파이썬에서 사실적이고 큰 프로그램을 작성하는 방법에 대해 알아보겠습니다.

 

Standalone Programs 

지금까지 Python의 대화형 인터프리터 내에서 다음과 같은 코드 조각을 작성하고 실행했습니다.

>>> print("This interactive snippet works.") This interactive snippet works. 

이제 첫 번째 독립 실행형 프로그램을 만들어 보겠습니다. 컴퓨터에서 Python 코드 한 줄이 포함된 test1.py이라는 파일을 만드십시오.

print("This standalone program works!")

>> 프롬프트는 없으며 Python 코드 한 줄만 표시됩니다. 다음 항목이 있는지 확인합니다.

인쇄 전에 라인에 자국이 없습니다.

텍스트 터미널 또는 터미널 창에서 Python을 실행하는 경우

Python 프로그램과 프로그램 파일 이름:

 

$ python test1.py
This standalone program works! 

지금까지 이 책에서 본 대화형 스니펫을 모두 파일로 저장하고 직접 실행할 수 있습니다. ▲를 잘라내어 붙여넣을 경우, 초기 >> 및 ...을(를) 삭제해야 합니다. (최종 공간을 확보합니다.)

 

Command-Line Arguments 

 

컴퓨터에서 다음 두 줄이 포함된 test2.py 파일을 만듭니다.

 

import sys 

print('Program arguments:', sys.argv)

이제 이 프로그램을 실행하려면 현재 버전의 Python을 사용하십시오. 이게 어떻게 보일지 알 수 있어요.

표준 셸 프로그램을 사용하는 Linux 또는 Mac OS X 터미널 창:

 

$ python test2.py
Program arguments: ['test2.py']
$ python test2.py tra la la
Program arguments: ['test2.py', 'tra', 'la', 'la'] 

Modules and the import Statement 

Python 코드를 두 개 이상의 파일에서 만들고 사용하는 한 단계 더 나아갈 것입니다. 모듈은 Python 코드의 파일일 뿐입니다.

이 책의 텍스트는 단어, 문장, 단락, 장 등의 계층 구조로 구성되어 있습니다. 그렇지 않으면 한두 페이지 후에 읽을 수 없습니다. 코드는 대략 비슷한 상향식 구성을 가지고 있습니다. 데이터 유형은 단어, 문장은 문장, 함수는 단락, 모듈은 장과 같습니다. 비유를 계속하자면, 이 책에서 제가 프로그래밍 8장에서 설명할 내용은 다른 모듈의 코드를 참조하는 것과 같습니다.

우리는 수입 명세서를 사용하여 다른 모듈의 코드를 참조합니다. 이렇게 하면 가져온 모듈의 코드와 변수를 프로그램에서 사용할 수 있습니다.

 

Import a Module 

가져오기 문을 가장 간단하게 사용하는 것은 가져오기 모듈입니다. 여기서 module은 .py 확장자가 없는 다른 Python 파일의 이름입니다. 기상 관측소를 시뮬레이션해서 기상 보고서를 출력해 봅시다. 하나의 메인 프로그램이 보고서를 인쇄하고, 단일 기능으로 별도의 모듈이 보고서에 사용된 날씨 설명을 반환합니다.

여기 메인 프로그램이 있습니다.py):

 

import report 

description = report.get_description() print("Today's weather:", description) 

다음은 모듈(report.py)입니다.

def get_description(): # see the docstring below? """Return random weather, just like the pros""" from random import choice 

possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows'] return choice(possibilities) 

이 두 파일이 동일한 디렉토리에 있고 Python이 weather▲ man.py을 메인 프로그램으로 실행하도록 지시하면, Python은 보고서 모듈에 액세스하여 get_tription tion 함수를 실행합니다. 문자열 목록에서 임의의 결과를 반환하기 위해 이 버전의 get_description()을 작성했습니다. 따라서 기본 프로그램은 다음과 같이 반환되고 인쇄됩니다.

 

$ python weatherman.py Today's weather: who knows $ python weatherman.py Today's weather: sun
$ python weatherman.py Today's weather: sleet 

우리는 수입품을 두 곳에서 사용했습니다.

• 메인 프로그램 weatherman.py에서 모듈 보고서를 가져왔습니다.

• 모듈 파일 report.py에서 get_discription unction 함수가 Python의 표준 랜덤 모듈에서 choice 함수를 가져왔습니다.

우리는 또한 수입품을 두 가지 다른 방법으로 사용했습니다.

• 주요 프로그램이 import report를 호출한 후 report.get_descrip을 실행했습니다.

이온화

• 랜덤 가져오기에서 호출된 report.py의 get_discription function

선택 후 실행(가능성)했습니다.

첫 번째 경우 보고서 모듈 전체를 가져오지만 report.를 접두사로 사용해야 get_description()이(가) 가능합니다. report.py의 모든 내용은 보고서 이름 앞에 있는 보고서만 붙이면 주 프로그램에서 사용할 수 있습니다. 모듈의 내용을 모듈 이름으로 한정함으로써 이름 충돌이 발생하는 것을 방지할 수 있습니다. 다른 모듈에 get_description() 함수가 있을 수 있으며 실수로 호출하지는 않습니다.

두 번째 경우에는 함수 내에 있고 여기에 다른 명명된 선택 항목이 없으므로 임의 모듈에서 선택() 함수를 직접 가져왔습니다. 임의의 결과를 반환하는 다음과 같은 함수를 작성할 수 있었습니다.

def get_description(): import random 

possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows'] return random.choice(possibilities) 

프로그래밍의 여러 가지 측면과 마찬가지로 자신에게 가장 명확해 보이는 스타일을 고르십시오. 모듈 인증 이름(랜덤).(선택)이 더 안전하지만 조금 더 입력해야 합니다.위의 get_description() 예제는 가져올 항목의 다양성을 보여 주었지만 가져올 위치의 다양성은 나타내지 않았습니다. 모두 함수 내부에서 가져오기라고 했습니다. 함수 외부에서 임의로 가져올 수 있었습니다.

 

>>> import random
>>> def get_description(): 

  •     ...     possibilities = ['rain', 'snow', 'sleet', 'fog', 'sun', 'who knows']
  •  
  • ...  return random.choice(possibilities) ...
    >>> get_description()
    'who knows'
    >>> get_description()
    'rain'

가져온 코드를 둘 이상의 장소에서 사용할 수 있는 경우 기능 외부에서 가져오고, 사용이 제한되는 경우 내부에서 가져오기를 고려해야 합니다. 일부 사람들은 코드의 모든 종속성을 명확히 하기 위해 모든 가져오기를 파일 맨 위에 놓는 것을 선호합니다. 어느 쪽이든 통한다.

 

  • mport a Module with Another Nam

우리의 주요 weatherman.py 프로그램에서 우리는 수입 보고서를 호출했습니다. 하지만 이름이 같은 다른 모듈이 있거나 더 니모닉하거나 더 짧은 이름을 사용하려는 경우 어떻게 해야 합니까? 이러한 경우 별칭을 사용하여 가져올 수 있습니다. 다음 별칭을 사용합니다.

  • import report as wr
    description = wr.get_description() print("Today's weather:", description)
  • Import Only What You Want from a Module

Python을 사용하면 모듈의 하나 이상의 부품을 가져올 수 있습니다. 각 부분은 원래 이름을 유지하거나 별칭을 지정할 수 있습니다. 먼저 보고서 모듈에서 원래 이름으로 get_description()을 가져오겠습니다.

 

  • from report import get_description description = get_description() print("Today's weather:", description)

이제 do_it로 가져옵니다.

  • from report import get_description as do_it description = do_it()
    print("Today's weather:", description)

Module Search Path 

이제 do_it로 가져옵니다.Python은 가져올 파일을 어디에서 찾습니까? 표준 sys 모듈에 저장된 디렉토리 이름과 ZIP 아카이브 파일 목록을 변수 경로로 사용합니다. 이 목록에 액세스하여 수정할 수 있습니다. 다음은 Mac에서 Python 3.3용 sys.path의 값입니다.

 

>>> import sys
>>> for place in sys.path: ... print(place)
... 

    /Library/Frameworks/Python.framework/Versions/3.3/lib/python33.zip

    /Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3

    /Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/plat-darwin

    /Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/lib-dynload

    /Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages

초기 빈 출력 라인은 현재 디렉토리를 나타내는 빈 문자열 ''입니다. sys.path에서 '가 처음인 경우 Python은 무언가를 가져오려고 할 때 현재 디렉토리를 먼저 찾습니다. 가져오기 보고서는 report.py을 찾습니다.

첫 번째 매치가 사용됩니다. 즉, 랜덤이라는 모듈을 정의하고 표준 라이브러리 이전의 검색 경로에 있는 경우 표준 라이브러리의 랜덤에 액세스할 수 없습니다.

 

Packages 

코드 한 줄에서 여러 줄 기능, 독립 실행형 프로그램, 동일한 디렉토리에 있는 여러 모듈로 이동했습니다. Python 응용 프로그램을 더 많이 확장할 수 있도록 모듈을 패키지라는 파일 계층으로 구성할 수 있습니다.

아마도 우리는 다음 날과 다음 주에 각각 다른 유형의 문자 예보를 원하는 것 같습니다. 이를 구조화하는 한 가지 방법은 소스라는 이름의 디렉터리를 만들고 그 안에 daily.py과 weekly.py이라는 두 개의 모듈을 만드는 것입니다. 각각은 예측이라는 기능을 가지고 있다. 일별 버전은 문자열을 반환하고 주별 버전은 7개 문자열 목록을 반환합니다.

여기 메인 프로그램과 두 개의 모듈이 있습니다. (enumerate() 함수는 목록을 분해하여 목록의 각 항목을 for 루프에 공급하여 각 항목에 숫자를 조금 더 추가합니다.)

주 프로그램: box/weather.py.

 

from sources import daily, weekly 

print("Daily forecast:", daily.forecast()) print("Weekly forecast:")
for number, outlook in enumerate(weekly.forecast(), 1): 

print(number, outlook) 

모듈 1: box/box/daily.py.

def forecast():
'fake daily forecast' return 'like yesterday' 

모듈 2: box/box/weekly.py.

def forecast():
"""Fake weekly forecast"""
return ['snow', 'more snow', 'sleet', 

'freezing rain', 'rain', 'fog', 'hail']

원본 디렉토리에 __init_.py라는 파일이 하나 더 필요합니다. 이 캔

비어 있지만 Python은 이 디렉터리를 패키지로 처리하려면 이 디렉터리가 필요합니다. 메인 weather.py 프로그램을 실행하여 다음 작업을 확인합니다.

$ python weather.py
Daily forecast: like yesterday Weekly forecast:
1 snow
2 more snow
3 sleet
4 freezing rain
5 rain
6 fog
7 hail 

The Python Standard Library 

Python의 주요 주장 중 하나는 Python이 많은 유용한 작업을 수행하는 대규모 표준 모듈 라이브러리인 "배터리 포함"을 가지고 있으며 핵심 언어가 과장되지 않도록 별도로 보관하고 있다는 것입니다. 일부 Python 코드를 작성하려고 할 때 먼저 원하는 작업을 이미 수행하는 표준 모듈이 있는지 확인하는 것이 좋습니다. 표준 도서관에서 작은 보석들을 자주 접하는 것은 놀라운 일입니다. Python은 또한 튜토리얼과 함께 모듈에 대한 권위 있는 설명서를 제공합니다. Doug Hellmann의 웹 사이트 Python Module of the Week와 그의 저서 The Python Standard Li bybrary by 예제(Addison-Wesley Professional)도 매우 유용한 가이드입니다.

책의 다음 장에서는 , 시스템, 데이터베이스 등과 관련된 많은 표준 모듈을 다룹니다. 섹션에서는 일반적인 용도가 있는 가지 표준 모듈에 대해 설명하겠습니다.

파이썬코드구조 closures

Closures 

내부 기능이 폐쇄 역할을 할 수 있습니다. 다른 함수에 의해 동적으로 생성되는 함수로, 함수 외부에서 생성된 변수의 값을 변경하고 기억할 수 있습니다.

다음 예제는 이전 기사() 예제를 기반으로 합니다. 우리는 상상력이 없기 때문에 새로운 기사2()라고 부르고, 내부() 기능을 내부2()라고 하는 폐쇄 기능으로 바꾸자. 차이점은 다음과 같습니다.

• inner2는 외부말 매개변수를 인수로 얻는 대신 직접 사용합니다.

• nights2px는 내부 2 함수 이름을 호출하는 대신 반환합니다.

 

>>> def knights2(saying): 

def inner2():
return "We are the knights who say: '%s'" % saying 

return inner2 

내부2() 함수는 전달된 말의 가치를 알고 기억합니다. line return inner2는 inner2 함수의 이 특수 복사본을 반환합니다(하지만 호출하지는 않음). 이것은 폐쇄입니다. 어디서 왔는지 기억하는 동적으로 만들어진 함수입니다.

다른 인수를 사용하여 기사 2()를 두 번 호출합니다.

 

>>> a = knights2('Duck') 

>>> b = knights2('Hasenpfeffer') 

좋아, 그럼 A와 B는 뭐야?

>>> type(a) <class 'function'> >>> type(b) <class 'function'> 

기능이지만 폐쇄이기도 합니다.

 >>> a

    <function knights2.<locals>.inner2 at 0x10193e158>

    >>> b

    <function knights2.<locals>.inner2 at 0x10193e1e0>

우리가 그들을 부른다면, 그들은 그들이 기사2에 의해 창조되었을 때 사용되었던 속담을 기억한다:

 >>> a()

    "We are the knights who say: 'Duck'"

    >>> b()

    "We are the knights who say: 'Hasenpfeffer'"

Anonymous Functions: the lambda() Function 

Python에서 람다 함수는 단일 문장으로 표현되는 익명 함수입니다. 일반적인 작은 기능 대신 사용할 수 있습니다.

 

이를 설명하기 위해 먼저 정규 함수를 사용하는 예를 만들어 보겠습니다. 먼저 edit_story() 함수를 정의하겠습니다. 그 주장은 다음과 같다.

• 단어—단어 목록

• func—단어의 각 단어에 적용하는 기능

 

>>> def edit_story(words, func): ... for word in words:
... print(func(word)) 

이제 단어 목록과 각 단어에 적용할 기능이 필요합니다. 여기 제 고양이가 계단 하나를 놓쳤을 때 내는 (가정적인) 소리 목록이 있습니다.

 

>>> stairs = ['thud', 'meow', 'thud', 'hiss']

그리고 함수의 경우, 각 단어를 대문자로 쓰고 느낌표를 붙입니다.

고양이 타블로이드 신문 헤드라인에 적합:

 

>>> def enliven(word): # give that prose more punch ... return word.capitalize() + '!' 

재료 혼합:

 >>> edit_story(stairs, enliven)

    Thud!

    Meow!

    Thud!

Hiss!

드디어 람다에 도착했군. 활성화() 기능이 너무 짧아서 대체할 수 있었습니다.

람다와 함께:

 

>>>
>>> edit_story(stairs, lambda word: word.capitalize() + '!') Thud!
Meow!
Thud!
Hiss!
>>> 

람다는 하나의 주장을 받아들입니다. 여기서 우리는 그것을 단어라고 부릅니다. 대장과 끝 괄호 사이의 모든 것이 함수의 정의입니다.

종종 람다를 사용하는 것보다 활력()과 같은 실제 기능을 사용하는 것이 훨씬 더 명확합니다. 람다는 그렇지 않으면 많은 작은 함수들을 정의해야 할 경우에 가장 유용합니다. 그리고 그것들을 모두 기억해야 합니다. 특히 그래픽 사용자 인터페이스에서 람다를 사용하여 콜백 함수를 정의할 수 있습니다. 예는 부록 A를 참조하십시오.

 

Generators 

생성기는 Python 시퀀스 생성 개체입니다. 이 기능을 사용하면 전체 시퀀스를 한 번에 만들고 메모리에 저장하지 않고도 잠재적으로 큰 시퀀스를 반복할 수 있습니다. 생성기는 반복측정기의 데이터 원본인 경우가 많습니다. 이전 코드 예제에서는 이미 범위()라는 이름을 사용하여 일련의 정수를 생성했습니다. Python 2에서 range()는 목록을 반환하여 메모리에 맞도록 제한합니다. Python 2에는 생성기 xrange()도 있으며, 이는 Python 3에서 일반 범위()가 되었다. 이 예제에서는 1에서 100까지의 모든 정수를 추가합니다.

 

    >>> sum(range(1, 101))

    5050

 

생성기를 통해 반복할 때마다 마지막으로 호출된 시간을 추적하고 다음 값을 반환합니다. 이는 이전 통화에 대한 메모리가 없고 항상 동일한 상태의 첫 회선에서 시작되는 일반 함수와는 다릅니다.

잠재적으로 큰 시퀀스를 만들고 코드가 너무 커서 제너레이터를 이해할 수 없는 경우 제너레이터 함수를 작성합니다. 정상 함수이지만 반환이 아닌 항복문으로 값을 반환합니다. 고유한 범위 버전()을 작성해 보겠습니다.

 

>>> def my_range(first=0, last=10, step=1): 

number = first while number < last: 

yield number number += step 

정상적인 기능입니다.

    >>> my_range

    <function my_range at 0x10193e268>

생성기 개체를 반환합니다.

  >>> ranger = my_range(1, 5)

    >>> ranger

    <generator object my_range at 0x101a0a168>

이 생성기 개체에 대해 반복할 수 있습니다.

>>> for x in ranger: ... print(x) ...
1 

2 3 4 

Decorators 

경우에 따라 소스 코드를 변경하지 않고 기존 함수를 수정하려고 할 수 있습니다. 일반적인 예는 전달된 인수를 확인하기 위해 디버깅 문을 추가하는 것입니다.

데코레이터는 한 함수를 입력으로 사용하고 다른 함수를 반환하는 함수입니다. Python 트릭 백을 자세히 살펴보고 다음을 사용합니다.

• *병력 및 **왜성

• 내부 기능

• 인수로서의 함수

document_it() 함수는 다음 작업을 수행할 장식자를 정의합니다.

• 함수의 이름과 인수 값을 인쇄합니다.

• 인수를 사용하여 함수 실행

• 결과 인쇄

• 수정된 기능을 사용할 수 있도록 반환

코드는 다음과 같습니다.

 

  • >>> def document_it(func): 

document_it()에 전달하는 함수는 document_it()가 추가하는 추가 문을 포함하는 새 함수를 제공합니다. 데코레이터는 실제로 func에서 코드를 실행할 필요가 없지만 document_it()는 func를 호출하여 func뿐만 아니라 모든 추가 결과를 얻을 수 있도록 합니다.

그래서 이걸 어떻게 사용하죠? 장식자를 수동으로 적용할 수 있습니다

  • >>> def add_ints(a, b):
  • ... returna+b ...
    >>> add_ints(3, 5)
    8
    >>> cooler_add_ints = document_it(add_ints) # manual decorator assignment >>> cooler_add_ints(3, 5)
    Running function: add_ints
     Positional arguments: (3, 5)
  •     Keyword arguments: {}
  •     Result: 8
  •     8
  • 위의 수동 데코레이터 할당 대신, 꾸미려는 함수 앞에 @decorator_name을 추가하십시오.

>>> @document_it
... def add_ints(a, b):
... returna+b
...
>>> add_ints(3, 5)
Start function add_ints Positional arguments: (3, 5) Keyword arguments: {} Result: 8
8 

기능별로 둘 이상의 데코레이터를 둘 수 있습니다. 결과를 제곱하는 square_it()라는 다른 장식가를 작성해 보겠습니다.

 

...

...

...

...

...

def new_function(*args, **kwargs): result = func(*args, **kwargs) return result * result 

return new_function 

함수에 가장 근접하게 사용된 데코레이터(decorator, 정의 바로 위)가 먼저 실행된 다음 그 위에 있는 데코레이터가 실행됩니다. 두 순서 모두 동일한 최종 결과를 제공하지만 중간 단계가 어떻게 변하는지 확인할 수 있습니다.

 

>>> @document_it
... @square_it
... def add_ints(a, b):
... returna+b
...
>>> add_ints(3, 5)
Running function: new_function Positional arguments: (3, 5) Keyword arguments: {}
Result: 64
64 

데코레이터 순서를 반대로 해 보겠습니다.

>>> @square_it
... @document_it
... def add_ints(a, b): ... returna+b
...
>>> add_ints(3, 5) Running function: add_ints 

Positional arguments: (3, 5)

    Keyword arguments: {}

    Result: 8

    64

Namespaces and Scope 

이름은 어디에 쓰이느냐에 따라 다른 것을 가리킬 수 있다. Python 프로그램에는 특정 이름이 고유하고 다른 네임스페이스의 동일한 이름과 관련이 없는 섹션 등 다양한 네임스페이스가 있습니다.

각 함수는 고유한 네임스페이스를 정의합니다. 주 프로그램에서 x라는 변수를 정의하고 함수에서 x라는 다른 변수를 정의하면 다른 변수를 나타냅니다. 그러나 벽을 뚫을 수 있습니다. 필요한 경우 다양한 방법으로 다른 네임스페이스의 이름에 액세스할 수 있습니다.

프로그램의 주요 부분은 글로벌 네임스페이스를 정의하므로 해당 네임스페이스의 변수는 글로벌 변수입니다.

함수 내에서 전역 변수의 값을 가져올 수 있습니다.

>>> animal = 'fruitbat'
>>> def print_global():
... print('inside print_global:', animal) ...
>>> print('at the top level:', animal)
at the top level: fruitbat
>>> print_global()
inside print_global: fruitbat 

그러나 전역 변수의 값을 가져와 함수 내에서 변경하려고 하면 다음 오류가 발생합니다.

 

>>> def change_and_print_global(): 

  • ...  print('inside change_and_print_global:', animal)
  •     ...      animal = 'wombat'
  •  
  • ...  print('after the change:', animal) ...
    >>> change_and_print_global()
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 2, in change_and_report_it
    UnboundLocalError: local variable 'animal' referenced before assignment

이 변수를 변경하면 이름이 동물인 다른 변수도 변경되지만 이 변수는 함수 내부에 있습니다.

 

  • >>> def change_local(): 

  >>> change_local()

    inside change_local: wombat 4330406160

    >>> animal

    'fruitbat'

    >>> id(animal)

    4330390832

이게 어찌된 일이냐? 첫 번째 줄은 동물이라는 글로벌 변수에 '과일배트' 문자열을 할당했습니다. change_local() 함수에도 animal이라는 변수가 있지만, 이 변수는 로컬 네임스페이스에 있습니다.

여기서는 Python 함수 ID()를 사용하여 각 객체에 대한 고유한 값을 인쇄하고 change_local() 내부의 변수 동물이 프로그램의 메인 레벨에서 동물과 같지 않음을 증명했습니다.

함수 내의 로컬 변수가 아닌 전역 변수에 액세스하려면 글로벌 키워드를 사용해야 합니다(이것이 올 것임을 알고 있었음: expiritive is been implicit):

>>> animal = 'fruitbat'
>>> def change_and_print_global(): 

  • ...  global animal
  •     ...      animal = 'wombat'
  •  
  • ...  print('inside change_and_print_global:', animal) ...
    >>> animal
    'fruitbat'
    >>> change_and_print_global()
    inside change_and_print_global: wombat
    >>> animal
    'wombat' 

함수 내에서 전역이라고 말하지 않으면 Python은 로컬 네임스페이스를 사용하며 변수는 로컬입니다. 기능이 완료되면 사라집니다.

Python은 네임스페이스의 내용에 액세스할 수 있는 두 가지 기능을 제공합니다. • locals()는 로컬 네임스페이스의 콘텐츠 사전을 반환합니다.

• globalsyspace는 글로벌 네임스페이스의 내용에 대한 사전을 반환합니다. 그리고 여기서 사용되고 있습니다.

 

  • >>> animal = 'fruitbat' >>> def change_local():

>>> print('globals:', globals()) # reformatted a little for presentation globals: {'animal': 'fruitbat',
'__doc__': None,
'change_local': <function change_it at 0x1006c0170>, 

'__package__': None,
'__name__': '__main__',
'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__builtins__': <module 'builtins'>}
>>> animal
'fruitbat' 

 

change_local() 내의 로컬 네임스페이스에는 로컬 변수 동물만 포함되어 있습니다. 글로벌 네임스페이스에는 별도의 글로벌 변수 동물과 여러 가지가 포함되어 있습니다.

 

Uses of _ and __ in Names 

두 개의 밑줄(__)로 시작하고 끝나는 이름은 Python 내에서 사용할 수 있도록 예약되어 있으므로 자신의 변수와 함께 사용하면 안 됩니다. 이 이름 지정 패턴은 응용 프로그램 개발자가 자체 변수에 대해 선택할 가능성이 낮기 때문에 선택되었습니다.

예를 들어, 함수의 이름은 시스템 변수 함수 ._name__에 있으며 문서화 문자열은 함수입니다.__doc__:

 

>>> def amazing(): 

  •     ...      '''This is the amazing function.
  •  
  •     ...      Want to see it again?'''
  •  
  • ...  print('This function is named:', amazing.__name__)
  • ...  print('And its docstring is:', amazing.__doc__) ...
    >>> amazing()
    This function is named: amazing
    And its docstring is: This is the amazing function.
    Want to see it again?

앞서 글로벌 인쇄물에서 보셨듯이, 메인 프로그램에는 특별 프로그램이 할당되어 있습니다.

이름 __main_.

 

  • Handle Errors with try and except 
  • 일부 언어에서는 오류가 특수 함수 반환 값으로 표시됩니다. Python은 관련 오류가 발생할 때 실행되는 코드: 예외를 사용합니다.
    위치를 벗어난 목록이나 튜플 또는 존재하지 않는 키를 가진 사전 액세스와 같은 일부 항목이 이미 있습니다. 경우에 따라 실패할 수 있는 코드를 실행하는 경우 잠재적인 오류를 차단하기 위해 적절한 예외 처리기도 필요합니다.
  • 예외가 발생할 수 있는 모든 위치에 예외 처리를 추가하여 사용자에게 상황을 알리는 것이 좋습니다. 문제를 해결하지 못할 수도 있지만 최소한 상황을 확인하고 프로그램을 정상적으로 종료할 수는 있습니다. 일부 기능에서 예외가 발생했지만 해당 기능에서 잡히지 않으면 일부 호출 기능에서 일치하는 핸들러에 잡힐 때까지 거품이 발생합니다. 사용자 고유의 예외 처리기를 제공하지 않는 경우 Python은 오류 메시지와 오류가 발생한 위치에 대한 일부 정보를 인쇄한 후 프로그램을 종료합니다.
  •   >>> short_list = [1, 2, 3]
  •     >>> position = 5
  •     >>> short_list[position]
  •     Traceback (most recent call last):
  • File "<stdin>", line 1, in <module> IndexError: list index out of range 

코드를 운에 맡기지 말고 코드를 래핑해 보십시오. 오류 처리 기능은 예외입니다.

 

>>> short_list = [1, 2, 3] >>> position = 5
>>> try:
... short_list[position] ... except: 

... print('Need a position between 0 and', len(short_list)-1, ' but got', ... position)
...
Need a position between 0 and 2 but got 5 

시도 블록 내부의 코드가 실행됩니다. 오류가 발생하면 예외가 발생하고 예외 블록 내부의 코드가 실행됩니다. 오류가 없으면 예외 블록을 건너뜁니다.

여기서처럼 인수가 없는 경우를 제외하고 평면을 지정하는 것은 모든 예외 유형에 대한 캐치올입니다. 둘 이상의 예외 유형이 발생할 수 있는 경우 각 예외 처리기를 별도로 제공하는 것이 가장 좋습니다. 이렇게 하도록 강요하는 사람은 없습니다. 모든 예외를 포착하는 것 외에는 베어(Bare)를 사용할 수 있지만 이러한 예외에 대한 처리가 일반적일 수 있습니다(일부 인쇄 오류가 발생했습니다). 원하는 수의 특정 예외 처리기를 사용할 수 있습니다.

때로는 유형을 벗어난 예외 세부 정보를 원할 수 있습니다. 다음 형식을 사용하는 경우 변수 이름에 전체 예외 개체가 표시됩니다.

except exceptiontype as name 

 

다음 예제에서는 시퀀스에 잘못된 위치를 제공할 때 IndexError가 발생하는 예외 유형이기 때문에 먼저 IndexError를 찾습니다. IndexError 예외는 변수에 저장하고 다른 예외는 변수에 저장합니다. 이 예에서는 다른 항목에 저장된 모든 내용을 인쇄하여 해당 개체에 있는 내용을 보여 줍니다.

 

>>> short_list = [1, 2, 3] >>> while True: 

...
...
...
... try: 

value = input('Position [q to quit]? ') if value == 'q': 

break 

    ...

    ...

    ...

    ...

    ...

    ...

    ...

    Position [q to quit]? 1

    2

    Position [q to quit]? 0

    1

    Position [q to quit]? 2

    3

    Position [q to quit]? 3

    Bad index: 3

    Position [q to quit]? 2

    3

Position [q to quit]? two
Something else broke: invalid literal for int() with base 10: 'two' Position [q to quit]? q 

위치 3을 입력하면 예상대로 인덱스 오류가 발생했습니다. 두 개를 입력하면 두 번째에 처리한 int() 함수가 코드만 제외하고 모두 잡힙니다.

 

Make Your Own Exceptions 

이전 섹션에서는 처리 예외에 대해 설명했지만, 모든 예외(예: IndexError)는 Python 또는 표준 라이브러리에 미리 정의되어 있습니다. 원하는 용도로 사용할 수 있습니다. 또한 프로그램에서 발생할 수 있는 특수한 상황을 처리하기 위해 고유한 예외 유형을 정의할 수도 있습니다.

예외는 수업이다. 예외 클래스의 하위 항목입니다. 대문자라는 예외를 만들자.문자열에 대문자가 있을 경우 예외로 올리고 대문자로 표시합니다.

 

>>> class UppercaseException(Exception): ... pass
>>> words = ['eeenie', 'meenie', 'miny', 'MO'] >>> for word in words:
... if word.isupper():
... raise UppercaseException(word) ... 

Traceback (most recent call last): File "<stdin>", line 3, in <module> 

    __main__.UppercaseException: MO

대문자에 대한 동작도 정의하지 않았습니다.예외(방금 통과를 사용함)를 통해 상위 클래스인 예외(Exception)가 예외가 발생했을 때 인쇄할 내용을 파악할 수 있습니다.

예외 개체 자체에 액세스하여 인쇄할 수 있습니다.

 

>>> try:
... raise OopsException('panic') ... except OopsException as exc: ... print(exc)
...
panic 

Things to Do 

4.1 guess_me 변수에 값 7을 할당합니다. 그런 다음 guess_me가 7보다 작으면 'too low', 7보다 크면 'too high', 7보다 크면 'just right' 문자열을 인쇄하는 조건부 테스트(if, elif)를 작성합니다.

4.2 변수 guess_me에 값 7을, 변수 시작에 값 1을 할당합니다. guess_me와 시작을 비교하는 시간 루프를 작성합니다. 시작이 내 짐작보다 작으면 너무 낮게 인쇄합니다. 시작이 guess_me이면 '찾았다!'를 인쇄하고 루프를 종료합니다. 시작할 경우

루프가 더 크죠

4.3 4.4 사용

4.5 반품 시 a 사용

4.6 사용

4.9 범위(10)에서 홀수를 반환하는 get_odds라는 생성기 함수를 정의합니다. 반환된 세 번째 값을 찾아 인쇄하려면 for 루프를 사용하십시오.

than guess_me, 'oops'를 인쇄하고 루프를 종료합니다. 끝에서 시작 증분

루프에서 목록 값을 인쇄합니다 [3, 2, 1, 0].

(10) 범위의 짝수 목록을 작성하기 위해 이해 목록을 작성합니다.

사전 정사각형을 만들기 위한 사전 이해. 범위(10) 키를 사용하고 각 키의 정사각형을 값으로 사용합니다.

범위(10)의 홀수에서 홀수 집합을 생성하도록 이해를 설정합니다. 발생기 이해는 문자열 'Got'을 반환하고, 값은 값을 반환합니다.

범위(10). for 루프를 사용하여 이 과정을 반복합니다.

4.8 목록을 반환하는 good라는 함수를 정의합니다 ['해리', '론', '헤르미온느'.

4.7 숫자 사용

4.10 함수를 호출할 때 '시작'을 인쇄하고 종료할 때 '끝'을 인쇄하는 테스트라는 데코레이터를 정의합니다.

4.11 OopsException이라는 예외를 정의합니다. 무슨 일이 일어나는지 보려면 이 예외를 제기하십시오. 그런 다음 이 예외를 잡기 위한 코드를 작성하고 'Caught a oops'를 인쇄합니다.

4.12 zipcope 사용하여 제목 = [습관의 창조물', [크루웰 페이트] 플롯 = [수녀가 괴물로 변한다', [유령 가게] 목록과 짝을 이루는 영화라는 사전을 만듭니다.