파이썬코딩

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

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

 

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)도 매우 유용한 가이드입니다.

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

파이썬코드 functions

Functions 

지금까지 Python 코드 예는 모두 작은 조각이었습니다. 이러한 기능은 소규모 작업에 유용하지만 항상 조각을 다시 입력하려는 사람은 없습니다. 우리는 더 큰 코드를 관리할 수 있는 조각으로 정리할 수 있는 방법이 필요합니다.

코드 재사용을 위한 첫 번째 단계는 다른 모든 코드와 별도로 명명된 코드 조각입니다. 함수는 임의의 숫자와 유형의 입력 매개 변수를 사용하고 임의의 숫자와 유형의 출력 결과를 반환할 수 있습니다.

기능을 사용하여 두 가지 작업을 수행할 수 있습니다.

 

Defineit • Callit 

Python 함수를 정의하려면 함수에 대한 입력 매개 변수를 포함하는 함수 이름인 def를 입력하고 마지막으로 콜론(:)을 입력합니다. 함수 이름은 변수 이름과 동일한 규칙을 가집니다(문자 또는 _로 시작하고 문자, 숫자 또는 _만 포함해야 함).

한 번에 한 단계씩 진행하고 먼저 파라미터가 없는 함수를 정의하고 호출합니다. 가장 간단한 Python 함수는 다음과 같습니다.

 

>>> def do_nothing(): ... pass 

이러한 매개변수가 없는 함수의 경우에도 정의에 괄호와 콜론이 필요합니다. if 문장으로 코드를 들여쓰는 것처럼 다음 줄을 들여써야 합니다. Python은 이 기능이 아무것도 하지 않는다는 것을 보여주기 위해 패스 문이 필요합니다. 이 페이지는 더 이상 표시되지 않더라도 일부러 비워둔 페이지와 같습니다.

이름과 괄호를 입력하기만 하면 이 기능을 호출할 수 있습니다. 광고된 대로 작동하며 제대로 작동하는 것은 없습니다.

 

  >>> do_nothing()

    >>>

이제 매개 변수는 없지만 단어 하나를 인쇄하는 다른 함수를 정의하여 호출하겠습니다.

 

>>> def make_a_sound(): ... print('quack') ...
>>> make_a_sound() quack 

make_a_sound() 함수를 호출했을 때, Python은 정의 내에서 코드를 실행했습니다. 이 경우, 한 단어를 인쇄하고 메인 프로그램으로 돌아갑니다.

매개 변수는 없지만 값을 반환하는 함수를 시도해 보겠습니다.

 

>>> def agree(): ... return True ... 

다음과 같은 경우 이 함수를 호출하고 반환된 값을 테스트할 수 있습니다.

>>> if agree():
... print('Splendid!')
... else:
... print('That was unexpected.') ...
Splendid! 

당신은 방금 큰 발걸음을 내디뎠어요. if 및 loop과 같은 테스트와 함수의 조합은 이전에 할 수 없었던 것을 가능하게 합니다.

이쯤에서 괄호 사이에 무언가를 넣어야 할 때입니다. echo() 함수를 anything 매개 변수 하나로 정의하겠습니다. 반환 문을 사용하여 호출자에게 다음 사이의 공백을 사용하여 값을 두 번 보냅니다.

>>> def echo(anything):
... return anything + ' ' + anything ...
>>> 

이제 'Rumplestiltskin' 문자열로 echo()를 호출하겠습니다.

>>> echo('Rumplestiltskin') 

    'Rumplestiltskin Rumplestiltskin'

함수를 호출할 때 함수에 전달되는 값을 인수라고 합니다. 인수를 사용하여 함수를 호출하면 해당 인수 값이 함수 내부의 해당 매개 변수에 복사됩니다. 이전 예에서는 echo() 함수를 'Rumplestiltskin' 인수 문자열로 호출했습니다. 이 값은 echo() 내에서 매개 변수에 복사된 다음 호출자에게 (이 경우 공백이 두 배로) 반환되었습니다.

이러한 기능 예는 매우 기초적이었다. 입력 인수를 사용하여 실제로 수행하는 함수를 작성해 보겠습니다. 색상에 대한 코멘트가 있는 이전 코드 조각을 수정하겠습니다. 주석이라고 하고 color라는 입력 문자열 매개변수를 사용하도록 합니다. 문자열 설명을 호출자에게 반환하고 호출자는 문자열로 수행할 작업을 결정합니다.

 

>>> def commentary(color): 

...
...
...
...
...
...
... else:
... return "I've never heard of the color " + color + "." ... 

>>> 

문자열 인수가 'blue'인 함수 주석()을 호출합니다.

>>> comment = commentary('blue') 

이 기능은 다음을 수행합니다.

• 함수의 내부 색상 매개변수에 '파란색' 값을 할당합니다

• if-elife-elife 논리 체인을 통해 실행

• 문자열을 반환합니다.

• 변수 설명에 문자열을 할당합니다. 무엇을 다시 얻을 수 있습니까?

 

>>> print(comment)
I've never heard of the color blue. 

함수는 모든 유형의 입력 인수(0 포함)를 수에 제한 없이 사용할 수 있습니다. 모든 유형의 출력 결과(0 포함)를 원하는 수만큼 반환할 수 있습니다. 함수가 명시적으로 호출되지 않으면 호출자는 없음 결과를 얻습니다.

 

>>> print(do_nothing()) None 

None Is Useful 

None은 할 말이 없을 때 자리를 유지하는 특별한 Python 값입니다. 부울 값으로 평가하면 거짓으로 표시되지만 부울 값 False와 동일하지는 않습니다. 예는 다음과 같습니다.

 

>>> thing = None
>>> if thing:
... print("It's some thing") ... else:
... print("It's no thing") ...
It's no thing 

없음과 부울 False 값을 구분하려면 Python의 is 연산자를 사용합니다.

>>> if thing is None:
... print("It's nothing") ... else:
... print("It's something") ...
It's nothing 

이것은 미묘한 구별처럼 보이지만 Python에서는 중요합니다. 결측값과 빈 값을 구분하려면 없음을 입력해야 합니다. 0 값 정수 또는 부동 소수, 빈 문자열(''), 목록([]), 튜플( (, )), 사전({}) 및 집합( )은 모두 False이지만 없음과 같지는 않습니다.

해당 인수가 없음인지 여부를 인쇄하는 빠른 함수를 작성하겠습니다.

 

 >>> is_none(None)

      It's None

      >>> is_none(True)

      It's True

      >>> is_none(False)

      It's False

      >>> is_none(0)

      It's False

      >>> is_none(0.0)

      It's False

      >>> is_none(())

      It's False

      >>> is_none([])

      It's False

      >>> is_none({})

      It's False

      >>> is_none(set())

      It's False

위치 인수

Python은 많은 언어에 비해 매우 유연한 방식으로 함수 인수를 처리합니다. 가장 친숙한 인수 유형은 위치 인수이며, 위치 인수의 값은 순서대로 해당 매개 변수에 복사됩니다.

이 함수는 위치 입력 인수를 사용하여 사전을 만들고 다음을 반환합니다.

>>> def menu(wine, entree, dessert):
... return {'wine': wine, 'entree': entree, 'dessert': dessert} ...
>>> menu('chardonnay', 'chicken', 'cake')
{'dessert': 'cake', 'wine': 'chardonnay', 'entree': 'chicken'} 

매우 흔하지만, 위치 논쟁의 단점은 각 위치의 의미를 다시 기억할 필요가 있다는 것입니다. 만약 우리가 잊고 와인과 함께 메뉴()를 첫 번째가 아닌 마지막 논쟁으로 부른다면, 식사는 매우 달라질 것이다.

  >>> menu('beef', 'bagel', 'bordeaux')

    {'dessert': 'bordeaux', 'wine': 'beef', 'entree': 'bagel'}

키워드 인수

위치 인수의 혼동을 방지하기 위해 함수의 정의와 다른 순서로 인수를 해당 매개 변수의 이름으로 지정할 수 있습니다.

  >>> menu(entree='beef', dessert='bagel', wine='bordeaux')

    {'dessert': 'bagel', 'wine': 'bordeaux', 'entree': 'beef'}

위치 인수와 키워드 인수를 혼합할 수 있습니다. 와인을 먼저 지정하고, 메뉴와 디저트에 키워드 인수를 사용합니다.

  >>> menu('frontenac', dessert='flan', entree='fish')

    {'entree': 'fish', 'dessert': 'flan', 'wine': 'frontenac'}

위치 인수와 키워드 인수가 모두 포함된 함수를 호출할 경우 위치 인수가 먼저 와야 합니다.

 

기본 매개변수 값 지정

매개변수에 대한 기본값을 지정할 수 있습니다. 호출자가 해당 인수를 제공하지 않는 경우 기본값이 사용됩니다. 이 싱겁게 들리는 기능은 실제로 매우 유용할 수 있습니다. 이전 예제를 사용하여:

 

>>> def menu(wine, entree, dessert='pudding'):
... return {'wine': wine, 'entree': entree, 'dessert': dessert} 

이번에는 디저트 인수 없이 메뉴()를 호출해 보십시오.

>>> menu('chardonnay', 'chicken') 

{'dessert': 'pudding', 'wine': 'chardonnay', 'entree': 'chicken'} 

인수를 제공하면 기본값 대신 사용됩니다.

  >>> menu('dunkelfelder', 'duck', 'doughnut')

    {'dessert': 'doughnut', 'wine': 'dunkelfelder', 'entree': 'duck'}

 

기본 인수 값은 함수를 실행할 때가 아니라 함수를 정의할 때 계산됩니다. 새로운 Python 프로그래머의 일반적인 오류는 목록이나 사전과 같은 가변 데이터 유형을 기본 인수로 사용하는 것입니다.

 

다음 테스트에서 buggy() 함수는 매번 빈 결과 목록과 함께 실행되고 arg 인수를 추가한 다음 단일 항목 목록을 인쇄해야 합니다. 하지만 버그가 있습니다. 처음 호출했을 때만 비어 있습니다. 두 번째로, 결과는 여전히 이전 통화의 항목 하나를 가지고 있습니다.

 

>>> def buggy(arg, result=[]): ... result.append(arg) ... print(result)
... 

>>> buggy('a')
['a']
>>> buggy('b') # expect ['b'] ['a', 'b'] 

다음과 같이 작성되었더라면 작동했을 것입니다.

>>> def works(arg):
... result = []
... result.append(arg) ... return result
...
>>> works('a')
['a']
>>> works('b')
['b'] 

수정 사항은 다른 정보를 전달하여 첫 번째 통화를 나타내는 것입니다.

>>> def nonbuggy(arg, result=None): ... if result is None:
... result = []
... result.append(arg) 

... print(result) ...
>>> nonbuggy('a') ['a'] 

    >>> nonbuggy('b')

    ['b']

 

*를 사용하여 위치 인수 수집

C 또는 C++에서 프로그래밍한 경우 Python 프로그램의 별표(*)가 포인터와 관련이 있다고 가정할 수 있습니다. 아니요, Python은 포인터가 없습니다.

함수 내부에서 매개변수와 함께 사용할 경우 별표는 변수 개수의 위치 인수를 매개변수 값의 튜플로 그룹화합니다. 다음 예에서 args는 print_args() 함수에 전달된 인수에서 비롯된 매개 변수 튜플입니다.

 

>>> def print_args(*args):
... print('Positional argument tuple:', args) ... 

인수를 사용하지 않고 호출하면 *args에서 아무 것도 얻을 수 없습니다.

 

>>> print_args() 

Positional argument tuple: ()

무엇을 주든 인수 튜플로 인쇄됩니다.

  >>> print_args(3, 2, 1, 'wait!', 'uh...')

    Positional argument tuple: (3, 2, 1, 'wait!', 'uh...')

이는 변수 개수의 인수를 허용하는 print()와 같은 함수를 작성할 때 유용합니다. 함수에 필요한 위치 인수도 있는 경우 *args는 끝에 가서 나머지 항목을 모두 잡습니다.

 

>>> def print_more(required1, required2, *args): ... print('Need this one:', required1) 

  • ...  print('Need this one too:', required2)
  • ...  print('All the rest:', args)
    ...
    >>> print_more('cap', 'gloves', 'scarf', 'monocle', 'mustache wax') Need this one: cap
        Need this one too: gloves
  •     All the rest: ('scarf', 'monocle', 'mustache wax')
  •  

*를 사용할 때 tuple 매개 변수 args를 호출할 필요는 없지만 Python에서는 일반적인 관용어입니다.

 

**를 사용하여 키워드 인수 수집

두 개의 별표(**)를 사용하여 키워드 인수를 사전으로 그룹화할 수 있습니다. 여기서 인수 이름은 키이고 값은 해당 사전 값입니다. 다음은 키워드 인수를 인쇄하는 print_kwargs() 함수를 정의하는 예제입니다.

 

  • >>> def print_kwargs(**kwargs):
  • ... print('Keyword arguments:', kwargs) ...

이제 키워드 인수를 사용하여 호출해 보십시오.

 

  >>> print_kwargs(wine='merlot', entree='mutton', dessert='macaroon')

    Keyword arguments: {'dessert': 'macaroon', 'wine': 'merlot', 'entree': 'mutton'}

 

함수에 들어 있는 콰르그스는 사전입니다.

위치 매개변수를 *args 및 **kwargs와 혼합할 경우 해당 순서에 따라 발생해야 합니다. args와 마찬가지로 이 키워드 매개 변수를 kwargs라고 할 필요는 없지만 일반적으로 사용됩니다.

 

문서 문자열

Python의 Zen은 가독성이 중요하다고 말합니다. 함수 본문 시작 부분에 문자열을 포함시켜 설명서를 함수 정의에 첨부할 수 있습니다. 다음은 함수의 docstring입니다.

 

>>> def echo(anything): 

  •     ...      'echo returns its input argument'
  •  
  • ...  return anything

원하는 경우 다음과 같이 문서 문자열을 상당히 길게 만들고 리치 형식을 추가할 수도 있습니다.

  • def print_if_true(thing, check): '''
            Prints the first argument if a second argument is true.
  •         The operation is:

  •             1. Check whether the *second* argument is true.

    2. If it is, print the *first* argument.

        '''

if check: print(thing) 

함수의 docstring을 인쇄하려면 Python help() 함수를 호출합니다. 함수의 이름을 전달하여 멋진 형식의 docstring과 함께 인수 목록을 가져옵니다.

 

>>> help(echo)
Help on function echo in module __main__: 

    echo(anything)

        echo returns its input argument

형식을 사용하지 않고 원시 문서 문자열만 보려면:

>>> print(echo.__doc__)
echo returns its input argument 

이상하게 생긴 __doc__은(는) 함수 내에서 변수로서 docstring의 내부 이름입니다. 103페이지의 "이름에서 _ 및 __의 사용"은 이 모든 밑줄 뒤에 숨겨진 이유를 설명합니다.

 

Functions Are First-Class Citizens 

파이썬의 모토를 언급했는데, 모든 것은 객체입니다. 여기에는 숫자, 문자열, 튜플, 목록, 사전 및 함수가 포함됩니다. 함수는 Python의 일급 시민권입니다. 변수를 변수에 할당하고 다른 함수에 인수로 사용하고 함수에서 반환할 수 있습니다. 이를 통해 다른 많은 언어로 수행하기가 어려운 Python에서 몇 가지 작업을 수행할 수 있습니다.

이를 테스트하기 위해 인수 없이 42만 인쇄하는 answer()라는 간단한 함수를 정의하겠습니다.

 

>>> def answer(): ... print(42) 

이 기능을 실행하면 다음과 같은 결과를 얻을 수 있습니다.

  >>> answer()

    42

이제 run_something이라는 다른 함수를 정의하겠습니다. 실행할 함수인 func라는 인수가 하나 있습니다. 일단 안으로 들어가면, 기능을 호출할 뿐입니다.

>>> def run_something(func): ... func() 

run_something()에 대한 답변을 전달하면 다른 thing와 마찬가지로 함수를 데이터로 사용합니다.

  >>> run_something(answer)

    42

답변()이 아닌 답변을 전달했습니다. Python에서 이 괄호는 이 함수를 호출하는 것을 의미합니다. 괄호 없이 Python은 다른 객체처럼 함수를 처리합니다. 다른 모든 Python과 마찬가지로 Python도 객체이기 때문입니다.

>>> type(run_something) <class 'function'> 

인수를 사용하여 함수를 실행해 보겠습니다. arg1과 arg2 두 숫자 인수의 합을 인쇄하는 add_args() 함수를 정의합니다.

>>> def add_args(arg1, arg2): ... print(arg1 + arg2) 

add_args()는 무엇입니까?

>>> type(add_args) 

<class 'function'>

이 시점에서 run_something_with_args()라는 함수를 정의하자.

인수:

• 기능—실행 기능

• arg1—펑크의 첫 번째 인수

• arg2—함수에 대한 두 번째 인수

 

>>> def run_something_with_args(func, arg1, arg2): ... func(arg1, arg2) 

run_something_with_args()를 호출할 때 호출자가 전달한 함수는 func 매개 변수에 할당되고 arg1과 arg2는 인수 목록에 이어지는 값을 가져옵니다. 그런 다음 괄호가 Python에게 명령했기 때문에 실행 중인 func(arg1, arg2)는 이러한 인수를 사용하여 해당 함수를 실행합니다.

function name add_args와 un_something_with_args() 인수 5와 9를 전달하여 테스트해 봅시다.

 

  >>> run_something_with_args(add_args, 5, 9)

    14

run_something_with_args() 함수 내에서 add_args 함수는 func 매개 변수에 할당되었고, 5는 arg1에 할당되었으며, 9는 arg2에 할당되었습니다. 이 작업은 실행되었습니다.

add_args(5, 9)

이를 *args 및 **kwargs 기법과 결합할 수 있습니다.

임의의 수의 위치 인수를 사용하고 합() 함수를 사용하여 합계를 계산한 다음 합계를 반환하는 검정 함수를 정의하겠습니다.

 

 

>>> def sum_args(*args): ... return sum(args) 

나는 이전에 합계를 언급한 적이 없다. 이 함수는 기본 제공 Python 함수로, int 또는 float 인수의 값 합계를 계산합니다.

함수와 이 함수에 전달하기 위한 임의의 수의 위치 인수를 사용하는 새 함수 run_with_positional_args()를 정의합니다.

 

>>> def run_with_positional_args(func, *args): ... return func(*args) 

자, 어서 불러봐:

 >>> run_with_positional_args(sum_args, 1, 2, 3, 4)

    10

 

Inner Functions 

다른 함수 내에서 함수를 정의할 수 있습니다.

>>> def outer(a, b): 

...

...

...

...

>>>

>>> outer(4, 7)

11

 

내부 기능은 루프 또는 코드 중복을 방지하기 위해 다른 기능 내에서 복잡한 작업을 이상 수행할 유용합니다. 문자열 예제의 경우 내부 함수는 인수에 일부 텍스트를 추가합니다.

파이썬코드 Iterate Multiple Sequences with zip()

Iterate Multiple Sequences with zip() 

 

zip() 함수를 사용하여 여러 시퀀스에 걸쳐 병렬로 반복하는 멋진 반복 트릭이 하나 더 있습니다

.>>> days = ['Monday', 'Tuesday', 'Wednesday']
>>> fruits = ['banana', 'orange', 'peach']
>>> drinks = ['coffee', 'tea', 'beer']
>>> desserts = ['tiramisu', 'ice cream', 'pie', 'pudding']
>>> for day, fruit, drink, dessert in zip(days, fruits, drinks, desserts): ... print(day, ": drink", drink, "- eat", fruit, "- enjoy", dessert) ... 

    Monday : drink coffee - eat banana - enjoy tiramisu

    Tuesday : drink tea - eat orange - enjoy ice cream

    Wednesday : drink beer - eat peach - enjoy pie

 

최단 시퀀스가 완료되면 zip이 중지됩니다. 목록(후식) 중 하나가 다른 목록보다 길어서 다른 목록을 확장하지 않으면 푸딩을 받을 수 없습니다.

 

이전포스팅의 "사전"은 딕트() 함수가 튜플, 목록 또는 문자열과 같은 두 항목 시퀀스에서 사전을 작성하는 방법을 보여줍니다. zip()을 사용하여 여러 시퀀스를 거닐고 동일한 간격띄우기에 있는 항목에서 튜플을 만들 수 있습니다. 해당하는 영어 단어와 프랑스어 단어 두 튜플을 만들어 봅시다.

 

    >>> english = 'Monday', 'Tuesday', 'Wednesday'

    >>> french = 'Lundi', 'Mardi', 'Mercredi'

 

이제 zip()을 사용하여 이 튜플을 페어링합니다. zip()으로 반환되는 값 자체는 튜플이나 목록이 아니라 다음 중 하나로 변환될 수 있는 테이블 값입니다.

 

    >>> list( zip(english, french) )

    [('Monday', 'Lundi'), ('Tuesday', 'Mardi'), ('Wednesday', 'Mercredi')]

 

zip()의 결과를 dict()에 직접 입력하고 voilà: 작은 영어-프랑스어 사전!

 

>>> dict( zip(english, french) ) 

{'Monday': 'Lundi', 'Tuesday': 'Mardi', 'Wednesday': 'Mercredi'} 

Generate Number Sequences with range() 

range() 함수는 지정된 범위 내의 숫자 스트림을 반환합니다. 먼저 목록이나 튜플과 같은 큰 데이터 구조를 만들고 저장할 필요가 없습니다. 이렇게 하면 컴퓨터의 모든 메모리를 사용하지 않고 프로그램을 손상시키지 않고도 큰 범위를 만들 수 있습니다.

범위()는 슬라이스를 사용하는 방법과 유사하게 사용합니다. 범위(시작, 중지, 단계) 시작을 생략하면 범위는 0에서 시작됩니다. 필요한 값은 중지뿐이며, 슬라이스와 마찬가지로 마지막으로 생성된 값은 중지 직전입니다. 스텝의 기본값은 1이지만 -1로 뒤로 돌아갈 수 있습니다.

zip()과 마찬가지로 range()는 테이블 가능한 개체를 반환하므로 ...에 대한 값을 단계별로 이동하거나 개체를 목록과 같은 시퀀스로 변환해야 합니다. 범위를 0, 1, 2로 설정합니다.

>>> for x in range(0,3): ... print(x)
...
0 

    1

    2

    >>> list( range(0, 3) )

    [0, 1, 2]

 

다음은 2 ~ 0 범위를 만드는 방법입니다.

>>> for x in range(2, -1, -1): ... print(x)
...
2 

1 

    0

    >>> list( range(2, -1, -1) )

    [2, 1, 0]

 

다음은 스텝 크기 2를 사용하여 0에서 10 사이의 짝수를 가져옵니다.

>>> list( range(0, 11, 2) ) 

[0,2,4,6,8,10] 

Other Iterators 

다음포스팅에서는 파일에 대한 반복을 보여줍니다. 이전포스팅에서는 사용자가 직접 정의한 객체 위에 반복을 설정하는 방법을 볼 수 있습니다.

 

Comprehensions 

이해는 한 명 이상의 반복기에서 Python 데이터 구조를 만드는 간단한 방법입니다. 이해를 통해 루프와 조건부 테스트를 세부 구문을 적게 조합할 수 있습니다. 이해력을 사용하는 것은 때때로 당신이 파이썬을 초보자 이상 알고 있다는 신호로 받아들여집니다. 다시 말해, 피토닉에 가깝죠.

 

List Comprehensions 

이렇게 한 번에 한 항목씩 1부터 5까지의 정수 목록을 작성할 수 있습니다.

>>> number_list = []
>>> number_list.append(1) >>> number_list.append(2) >>> number_list.append(3) >>> number_list.append(4) >>> number_list.append(5) >>> number_list [1,2,3,4,5] 

또는 반복기와 범위() 함수를 사용할 수도 있습니다.

>>> number_list = []
>>> for number in range(1, 6): ... number_list.append(number) ...
>>> number_list
[1,2,3,4,5] 

또는 범위()의 출력을 목록으로 직접 변환할 수 있습니다.

>>> number_list = list(range(1, 6)) >>> number_list
[1,2,3,4,5] 

이러한 접근 방식은 모두 유효한 Python 코드이며 동일한 결과를 생성합니다. 그러나 목록을 작성하는 더 많은 피토닉 방법은 목록 이해를 사용하는 것입니다. 목록 이해의 가장 간단한 형태는 다음과 같습니다.

[ 아이템에 대한 식을(를) 반복할 수 없습니다.

다음은 목록 이해에서 정수 목록을 작성하는 방법입니다.

 

>>> number_list = [number for number in range(1,6)] >>> number_list
[1,2,3,4,5] 

첫 번째 행에서 목록의 값을 생성하기 위한 첫 번째 숫자 변수가 필요합니다. 즉, 루프 결과를 number_list에 넣습니다. 두 번째 숫자는 for 루프의 일부입니다. 첫 번째 숫자가 식임을 표시하려면 다음 변형을 시도해 보십시오.

>>> number_list = [number-1 for number in range(1,6)] >>> number_list
[0,1,2,3,4] 

목록 이해에 따라 대괄호 안의 루프가 이동합니다. 이 이해 예시는 이전 예보다 간단하지 않지만, 더 있습니다. list comà 이해에는 다음과 같은 조건식이 포함될 수 있습니다.

[ 조건일 경우 반복할 수 없는 항목에 대한 표현식 ]

1과 5 사이의 홀수 목록만 작성하는 새로운 이해를 만들어 봅시다(홀수일 경우 %2이 참이고 짝수일 경우 거짓임을 기억하십시오.

>>> a_list = [number for number in range(1,6) if number % 2 == 1] >>> a_list
[1, 3, 5] 

이제, 이해는 전통적인 이해 방식보다 조금 더 좁습니다.

>>> a_list = []
>>> for number in range(1,6): ... ifnumber%2==1: 

...

...

>>>  a_list

[1, 3, 5]

a_list.append(number)

 

마지막으로, 내포된 루프가 있을 수 있는 것처럼, 해당 이해에 ...용 절이 두 개 이상 있을 수 있습니다. 먼저 일반 중첩 루프를 사용해 결과를 인쇄해 보겠습니다.

>>> rows = range(1,4) >>> cols = range(1,3) >>> for row in rows: 

  • ...  for col in cols:
  • ...  print(row, col)

... 

11 12 21 22 31 32 

이제 이해를 사용하여 변수 셀에 할당하여 (행, 콜) 튜플 목록을 만듭니다.

>>> rows = range(1,4)
>>> cols = range(1,3)
>>> cells = [(row, col) for row in rows for col in cols] >>> for cell in cells:
... print(cell)
...
(1, 1)
(1, 2)
(2, 1)
(2, 2)
(3, 1)
(3, 2) 

또한 튜플 언팩을 사용하여 셀 목록에서 반복하면서 각 튜플의 행 및 col 값을 유크할 수 있습니다.

 

>>> for row, col in cells: ... print(row, col) ...
11 

12 21 22 31 32 

앞줄과 뒷줄에 대한 이해도의 파편도 만약 테스트를 했다면 그들만의 파편을 가질 수 있었을 것이다.

 

Dictionary Comprehensions 

단순히 목록만으로 뒤지지 않기 위해 사전도 이해력이 있다. 가장 간단한 양식은 친숙해 보입니다.

{key_expression : interitable 식에 대한 value_expression}

목록 이해와 마찬가지로 사전 이해도 테스트와 사전 이해도 함께 가질 수 있습니다.

절의 경우 다중:

 

>>> word = 'letters' 

>>> letter_counts = {letter: word.count(letter) for letter in word} 

  >>> letter_counts

    {'l': 1, 'e': 2, 't': 2, 'r': 1, 's': 1}

우리는 '문자' 문자열의 일곱 글자 각각에 루프를 돌리고 그 글자가 몇 번 표시되는지 세고 있습니다. 우리가 사용하는 단어 중 두 개는 모든 e와 모든 t를 두 번 세야 하기 때문에 시간 낭비입니다. 하지만, 우리가 e를 두 번째로 셀 때, 우리는 이미 있던 사전의 항목을 교체하기 때문에 해를 끼치지 않습니다; t를 셀 때도 마찬가지입니다. 그래서, 다음은 조금 더 피토닉했을 것이다.

 

>>> word = 'letters'
>>> letter_counts = {letter: word.count(letter) for letter in set(word)} >>> letter_counts
{'t': 2, 'l': 1, 'e': 2, 'r': 1, 's': 1} 

집합(워드)을 반복하면 문자열 단어를 반복하는 순서와 다른 순서로 문자가 반환되기 때문에 사전의 키는 이전 예와 다른 순서로 정렬됩니다.

 

Set Comprehensions 

누구도 소외되고 싶어하지 않기 때문에 세트도 이해력이 있다. 가장 간단한 버전은 방금 본 목록과 사전 이해도처럼 보입니다.

{식 interitable}

긴 버전(테스트의 경우 절에 대해 여러 개)도 다음 집합에 대해 유효합니다.

>>> a_set = {number for number in range(1,6) if number % 3 == 1} >>> a_set
{1, 4} 

 

Generator Comprehensions 

튜플은 이해력이 없습니다! 목록 이해의 대괄호를 괄호로 변경하면 튜플 이해가 생성된다고 생각했을 수 있습니다. 그리고 다음과 같이 입력하면 예외가 없기 때문에 작동하는 것으로 보입니다.

>>> number_thing = (number for number in range(1, 6))

괄호 사이에 있는 것은 발전기 이해이며, 그것은 gen‐를 반환한다.

연산자 객체:

 

>>> type(number_thing) 

<class 'generator'>

발전기에 대해 더 자세히 알아보겠습니다(98페이지의 "발전기"). 발전기는 한 가지 방법이다.

반복자에게 데이터를 제공합니다.

다음 그림과 같이 이 생성기 개체에 대해 직접 반복할 수 있습니다.

>>> for number in number_thing: ... print(number)
...
1 

2 3 4 5 

또는 생성기 이해에 목록() 통화를 줄여서 목록 이해처럼 작동할 수 있습니다.

 

>>> number_list = list(number_thing) >>> number_list
[1,2,3,4,5] 

생성기는 한 번만 실행할 수 있습니다. 목록, 세트, 문자열 및 사전은 메모리에 존재하지만 생성기는 즉시 값을 생성하여 반복기를 통해 한 번에 하나씩 전달합니다. 이러한 구성 요소를 기억하지 못하므로 생성기를 다시 시작하거나 백업할 수 없습니다.

 

이 제너레이터를 다시 반복하려고 하면 다음과 같이 탭이 되어 있습니다.

   >>> try_again = list(number_thing)

    >>> try_again

    []

여기서와 같이 발전기를 이해하거나 발전기 기능을 통해 발전기를 만들 있습니다. 먼저 일반적인 기능에 대해 이야기한 발전기 기능의 특수한 사례에 대해 알아보겠습니다.