Setup Blender – Installing from Steam

Installing from Steam

Steam은 소프트웨어 배포 플랫폼입니다. Linux, macOS 또는 Windows에서 아래 설명된 단계에 따라 Steam 클라이언트를 사용하여 Blender를 다운로드하고 업데이트할 수 있습니다.

운영 체제에 맞는 Steam 클라이언트를 다운로드하세요. 설치가 완료되면 클라이언트를 열고 Steam 계정에 로그인하세요. 아직 계정이 없다면 계정을 만드세요. 로그인 후, 스토어 탭으로 이동하여 “Blender”를 검색한 후 녹색 설치 버튼을 누르세요. 이제 Steam 클라이언트의 라이브러리 탭에서 Blender를 사용할 수 있습니다.

Linux 및 Windows의 Steam에서 Blender를 설치할 때 .blend 파일 이름 확장자는 Blender와 자동으로 연결되지 않습니다. 블렌드 파일을 Blender와 연결하려면 LinuxWindows 설치 페이지에 설명된 프로세스를 참조하세요.

Updating with Steam

Steam에서 Blender 업데이트가 제공되면 Steam이 자동으로 Blender를 업데이트합니다.

References

Setup Blender – Installing on Windows

Installing on Windows

Blender 다운로드 페이지를 확인하여 최소 요구 사항과 Blender에 사용할 수 있는 다양한 버전을 확인하세요(아직 확인하지 않은 경우).

zip 파일 또는 Windows Installer 파일을 다운로드합니다.

Install from Windows Installer File

Windows 설치 프로그램을 사용하면 설치 폴더를 선택할 수 있으며 시작 메뉴에 항목을 생성하고 블렌더와 블렌드 파일을 연결할 수 있습니다. 설치를 위해 관리자 권한이 필요합니다.

Install from Zip

zip 파일을 선택할 때 Blender를 원하는 폴더에 수동으로 압축해지를 하여, 그 안의 실행 파일을 두 번 클릭하여 Blender를 실행할 수 있습니다.

시작 메뉴에 숏컷이 자동으로 생성되지 않고 블렌드 파일 연결이 등록되지 않지만 이렇게 설치하면 관리자 권한이 필요하지 않습니다. 환경 설정의 시스템 탭에서 “기본값으로 설정”을 클릭하여 파일을 수동으로 연결 할 수 있습니다. 혹은 터미널에서 커맨드라인 명령어 blender -r을 실행해도 같은 결과를 기대할 수 있습니다.

간편한 설치 방법:
모든 구성 파일과 설치된 추가 기능을 실행 폴더에 유지하려면 압축을 푼 폴더의 LOCAL 디렉터리config라는 폴더를 만듭니다.

Install from Microsoft Store

Microsoft Store에서 Blender를 검색하여 설치하면 Microsoft Store에서 Blender를 설치할 수 있습니다.

이렇게 설치를 하는 경우 Windows 시작 메뉴에 블렌더가 자동으로 추가됩니다.

Updating on Windows

Windows에서는 Blender를 업데이트하는 다양한 방법이 있습니다. 이 섹션에서는 가장 일반적인 접근 방식을 다룹니다.

Updating from Windows Installer File

Blender 업데이트가 출시되면 Blender 웹사이트에서 직접 다운로드할 수 있습니다. 그런 다음 Windows 설치 프로그램을 실행하여 업데이트된 Blender 버전을 설치할 수 있습니다. 이전에 설치한 Blender 버전을 제거하려면 Windows 설정이나 제어판을 사용하여 원하는 버전을 삭제하세요.

Updating from Zip

Blender용 업데이트가 출시되면 Blender 웹사이트에서 직접 다운로드하여 원하는 폴더에 압축을 푼 다음 실행 파일을 두 번 클릭하여 Blender를 실행할 수 있습니다. 간편 버전의 Blender 생성에 대한 자세한 내용은 Zip에서 설치 섹션을 참조하세요.

기존 블렌더 설치파일을 덮어쓸 필요는 없습니다. 블렌더는 하나의 장비에 여러개의 버전을 설치하는것이 가능합니다.

Updating from the Microsoft Store

Microsoft Store에서 Blender용 업데이트를 사용할 수 있게 되면 자동으로 다운로드되어 설치됩니다.

이전 Blender 버전 및 기타 빠른 설정에서 설정 가져오기에 대한 정보는 스플래시 화면 기본페이지에서 확인하세요.

References

Setup Blender – Installing on macOS

Installing on macOS

Blender 다운로드 페이지를 확인하여 최소 요구 사항과 Blender에 사용할 수 있는 다양한 버전을 확인하세요(아직 확인하지 않은 경우).

Install from DMG

macOS용 Blender는 디스크 이미지(dmg 파일)로 배포됩니다. 디스크 이미지를 마운트하려면 dmg 파일을 두 번 클릭하세요. 그런 다음 Blender.app을 응용 프로그램 폴더로 드래그하세요.

Mac의 보안 및 개인 정보 보호 기본 설정에 따라 macOS는 처음으로 Blender를 열기 전에 승인을 요청합니다.

휴대용 설치 방법
Blender 애플리케이션 번들 내에 모든 구성 파일과 설치된 추가 기능을 유지하려면 LOCAL 디렉터리에 config라는 폴더를 만듭니다.
./Blender.app/Contents/Resources/4.0/config/

Updating on macOS

macOS에는 Blender를 업데이트하는 다양한 방법이 있습니다. 이 섹션에서는 가장 일반적인 접근 방식을 다룹니다.

Updating with DMG

Blender 업데이트가 출시되면 Blender 웹사이트에서 직접 다운로드할 수 있습니다. 응용 프로그램 폴더에 있는 현재 Blender.app을 덮어써서 새 버전을 설치하세요. Blender.app의 이름을 바꾸거나 다른 폴더에 배치하여 한 번에 두 개 이상의 버전을 가질 수 있습니다.

이전 Blender 버전 및 기타 빠른 설정에서 설정 가져오기에 대한 정보는 스플래시 화면 기본페이지에서 확인하세요.

References

Setup Blender – Installing on Linux

Installing on Linux

Blender 다운로드 페이지를 확인하여 최소 요구 사항과 Blender에 사용할 수 있는 다양한 버전을 확인하세요(아직 확인하지 않은 경우).

Install from blender.org

해당 아키텍처에 맞는 Linux 버전을 다운로드하고 원하는 위치(예: ~/software 또는 /usr/local)에 파일의 압축을 풉니다.

이제 실행 파일을 두 번 클릭하여 블렌더를 시작할 수 있습니다.

이 설치 방법을 사용하면 여러 버전의 Blender를 설치할 수 있습니다.

간편한 액세스를 위해 메뉴 항목이나 Blender 바로가기를 추가하여 시스템을 구성할 수 있습니다. 블렌드 파일을 블렌더와 연결하여 파일 브라우저에서 선택하면 블렌더에서 자동으로 열릴 수도 있습니다. 이러한 설정은 일반적으로 창 관리자 설정과 함께 발견됩니다. (Gnome 또는 KDE.)

Install from Package Manager

일부 Linux 배포판의 repository에는 Blender용 특정 패키지가 있을 수 있습니다.

배포판의 기본 메커니즘을 통해 Blender를 설치하면 시스템의 다른 패키지와의 일관성이 보장되며 패키지 목록, 업데이트 알림 및 자동 메뉴 구성과 같은 다른 기능(패키지 관리자가 제공)을 제공할 수 있습니다. 그러나 패키지는 최신 공식 릴리스에 비해 오래되었거나 Blender의 일부 기능이 포함되어 있지 않을 수 있습니다. 예를 들어, 일부 배포판에서는 라이센스 또는 기타 이유로 Cycles GPU 렌더링 지원을 갖춘 Blender를 구축하지 않습니다.

배포판에 대한 특정 패키지가 있는 경우 가장 선호되고 가장 편리한 패키지를 선택할 수 있습니다. 그렇지 않은 경우 공식 바이너리는 blender.org에서 사용할 수 있습니다.

Install from Snap

Snap은 다양한 배포판에서 작동하도록 설계된 범용 패키지 관리자입니다. 스냅이 이미 설치되어 있다고 가정하면 다음과 같이 스냅을 통해 블렌더를 설치할 수 있습니다.

snap install blender --classic

이 방법으로 설치하면 Blender 업데이트가 자동으로 설치된다는 이점이 있습니다. Snap의 Blender는 개별 패키지 관리자보다 더 일관된 배포를 가져야 합니다.

Running from the Terminal

Launching from the terminal를 참고해 주세요.

Graphics System (X11 & Wayland)

Blender는 X11과 Wayland를 모두 지원합니다. 자세한 내용은 Linux Windowing Environment를 참조하세요.

Avoiding Alt-Mouse Conflict

일부 창 관리자는 창 이동 및 크기 조정을 위해 기본적으로 Alt-마우스왼쪽버튼Alt-마우스오른쪽버튼를 사용합니다.

블렌더는 특히 다음과 같은 다양한 작업에 이를 사용합니다.

Blender의 전체 기능 세트에 액세스하려면 대신 Meta 키(Super 또는 Windows 키라고도 함)를 사용하도록 창 관리자 설정을 변경할 수 있습니다.

Gnome

명령줄에 다음을 입력합니다(컴퓨터 재로그인 하셔야 적용된 내용을 확인 하실 수 있습니다).

gsettings set org.gnome.desktop.wm.preferences mouse-button-modifier '<Super>'

KDE

시스템 설정 ▸ 윈도우 관리 ▸ 윈도우 동작 ▸ 윈도우 액션, ‘Alt’ 키에서 ‘Meta’ 키로 전환하세요.

Updating on Linux

Linux에는 Blender를 업데이트하는 다양한 방법이 있습니다. 이 섹션에서는 가장 일반적인 접근 방식을 다룹니다.

Updating from blender.org

Blender용 업데이트가 출시되면 Blender 웹사이트에서 직접 다운로드하여 blender.org에서 설치 섹션에 설명된 단계를 사용하여 설치할 수 있습니다.

Updating with a Package Manager

많은 Linux 배포판에는 배포판의 패키지 관리자를 사용하여 설치할 수 있는 Blender용 패키지가 있습니다. 설치 후 다른 응용 프로그램을 업데이트하는 것과 동일한 단계를 사용하여 Blender를 업데이트할 수 있습니다.

이전 Blender 버전 및 기타 빠른 설정에서 설정 가져오기에 대한 정보는 스플래시 화면 기본페이지에서 확인하세요.

References

Setup Blender – Installing

Installing Blender

Blender는 대략 3개월마다 출시됩니다. 릴리스 노트를 통해 최신 변경 사항을 최신 상태로 유지할 수 있습니다.

System Requirements

블렌더는 Windows, macOS, Linux에서 다운로드할 수 있습니다. 그래픽 드라이버가 최신 상태인지, OpenGL이 제대로 지원되는지 항상 확인하세요. 블렌더에는 최소 및 권장 요구 사항이 있습니다. 따라서 Blender를 설치하기 전에 이러한 사항이 충족되는지 확인하세요.

그래픽 태블릿 및 3D 마우스와 같은 기타 하드웨어에 대한 지원은 나중에 하드웨어 구성에서 다룹니다.

Download Blender

블렌더는 안정성 수준에 따라 선택할 수 있는 다양한 바이너리 패키지를 제공합니다. 각 패키지에는 최신 기능과 안정성이 절충됩니다. 귀하에게 적합한 패키지는 이 두 가지에 대한 요구 사항에 따라 다릅니다. 예를 들어, 스튜디오는 장기적인 지원을 원할 수 있고, 취미로 즐기는 사람은 새로운 기능을 원할 수 있으며, 다른 스튜디오는 단지 향후 기능을 테스트하고 싶을 수도 있습니다. 여러분이 무엇을 찾으시든 아래에 설명된 각 패키지 중에 본인에게 딱 맞는 것이 있을거에요.

안정적인 릴리스(Stable Release)
최신 기능을 포함하고 회귀 없이 안정적인 것으로 간주되는 패키지입니다. 새로운 안정 버전은 약 3개월마다 제공됩니다.

장기 지원(Long-term Support)
매우 안정적인 Blender 버전이 필요한 오래 지속되는 프로젝트를 위해 설계된 패키지입니다. LTS 릴리스는 2년 동안 지원되며 새로운 기능, API 변경 또는 개선 사항이 없습니다. 매년 새로운 장기 지원 버전이 출시됩니다.

일일 빌드(Daily Builds)
최신 개발 변경 사항을 포함하도록 매일 업데이트되는 패키지입니다. 이러한 버전은 안정 릴리스만큼 철저하게 테스트되지 않았으며 공식적이고 일반적으로 실험적이지는 않지만 중단될 수 있습니다.

Blender의 소스 코드는 무료로 참조하거나 소스에서 빌드할 수 있습니다. 일반 사용자는 Blender를 컴파일할 것으로 예상되지 않지만 다음과 같은 장점이 있습니다.

  • 블렌더는 항상 최신 상태입니다.
  • 이를 통해 기능이 개발 중인 모든 버전이나 분기에 액세스할 수 있습니다.
  • 사용자의 요구에 맞춰 자유롭게 새로운 버젼을 직접 개발해서 사용할 수 있습니다.

최신 안정 릴리스이든 일일 빌드이든 바이너리를 설치하는 절차는 동일합니다. 플랫폼에 맞는 단계를 따르세요.

블렌더에는 업데이트 시스템이 내장되어 있지 않습니다. 이는 아래 섹션에 설명된 업그레이드 단계에 따라 Blender를 직접 업데이트해야 함을 의미합니다.

Installation Guides

References

About Blender – Community

The Blender Community

비공개 소스임에도 불구하고 처음부터 무료로 사용할 수 있다는 점은 커뮤니티에서 Blender를 채택하는 데 상당한 도움이 되었습니다. 매우 광범위하고 안정적이며 활동적인 사용자 커뮤니티가 1998년부터 Blender 주변에 모였습니다. 커뮤니티는 2002년에 Blender가 GNU GPL 라이센스에 따라 오픈 소스로 전환될 수 있도록 7주 만에 €100,000를 모금하는 데 도움을 주면서 Blender에 대한 전폭적인 지원을 보여주었습니다.

Independent Sites

포럼, 블로그, 뉴스, Blender 전용 튜토리얼 사이트 등 여러 독립 웹사이트가 있습니다.

가장 큰 커뮤니티 포럼 중 하나는 Blender 사용자가 모여 자신의 창작물을 선보이고, 피드백을 받고, 도움을 요청하고 제공하며, 일반적으로 Blender에 대해 토론하는 Blender Artists입니다.

Getting Support

Blender의 커뮤니티는 가장 큰 기능 중 하나이므로 이 사용 설명서 외에도 Blender Chat, Stack Exchange, Reddit 등 다른 사용자로부터 지원을 받을 수 있는 다양한 방법이 있습니다.

스튜디오와 기업에는 엔터프라이즈 지원이 있으며, 파이프라인에 Blender를 추가하려는 스튜디오를 위해 Blender Studio에는 이 주제와 관련된 문서와 교육 자료가 포함되어 있습니다. Blender에서 문제를 발견했다고 생각되면 버그를 신고해 주세요.

지원에 대한 자세한 내용은 지원 페이지에서 확인할 수 있습니다.

Development

오픈 소스이기 때문에 Blender는 자원봉사자의 개발을 환영합니다. 개발자 간의 커뮤니케이션은 주로 다음 세 가지 플랫폼을 통해 이루어집니다.

Blender 개발에 관심이 있다면 참여하기 페이지를 참조하세요.

Blender Chat

실시간 토론을 위해 인증을 위해 Blender ID를 사용하는 blender.chat이 있습니다.

다음 채널에 가입할 수 있습니다:

  • #today 커뮤니티로부터 답변을 얻기 위해.
  • #blender-coders 개발자가 블렌더 개발에 대해 논의할 수 있도록 합니다.
  • #python Python API를 사용하는 개발자를 지원합니다.
  • #docs Blender 문서와 관련된 토론입니다.

Other Useful Links

References

About Blender – License

About Free Software and the GPL

“free 소프트웨어”라는 말을 들을 때 가장 먼저 떠오르는 것은 “공짜”일 것입니다. 이것이 사실인 경우가 많지만, Free Software Foundation (GNU 프로젝트의 창시자이자 GNU General Public License의 창시자)이 사용하는 “free 소프트웨어”라는 용어는 free 맥주할때 공짜라는 뜻이 아니라 “freedom의 자유”를 의미합니다. 이러한 의미에서 free 소프트웨어는 제한 없이 자유롭게 사용, 복사, 수정, 재배포할 수 있는 소프트웨어입니다. 이는 단일 컴퓨터에 소프트웨어를 로드할 수 있고 복사본을 만들 수 없으며 소스 코드를 볼 수 없는 대부분의 상용 소프트웨어 패키지 라이센스와 대조됩니다. 무료 소프트웨어는 최종 사용자에게 놀라운 자유를 제공합니다. 소스 코드가 보편적으로 사용 가능하기 때문에 버그를 잡아서 수정할 가능성도 더 높습니다.

프로그램이 GNU General Public License(GPL)에 따라 라이센스가 부여된 경우:

  • 귀하는 어떤 목적으로든 프로그램을 사용할 권리가 있습니다.
  • 귀하는 프로그램을 수정하고 소스 코드에 접근할 수 있는 권리가 있습니다.
  • 귀하는 프로그램을 복사하고 배포할 권리가 있습니다.
  • 귀하는 프로그램을 개선하고 자신의 버전을 출시할 권리가 있습니다.

이러한 권리에 대한 대가로 GPL 프로그램을 배포하는 경우 몇 가지 책임이 있습니다. 이러한 책임은 귀하의 자유와 타인의 자유를 보호하기 위해 고안되었습니다.

  • 수신자가 라이센스에 따른 자신의 권리를 알 수 있도록 프로그램과 함께 GPL 사본을 제공해야 합니다.
  • 소스 코드를 포함하거나 소스 코드를 자유롭게 사용할 수 있도록 해야 합니다.
  • 코드를 수정하고 수정된 버전을 배포하는 경우 GPL(또는 호환 라이센스)에 따라 사용 가능한 수정 사항에 대한 라이센스를 받아야 합니다.
  • GPL 조건 이상으로 프로그램 라이센스를 제한할 수 없습니다(GPL 프로그램을 독점 제품으로 전환할 수 없습니다).

GPL에 대한 자세한 내용은 GNU 프로젝트 웹사이트에서 해당 페이지를 확인하세요.

GPL은 블렌더 애플리케이션에만 적용되며 이를 사용하여 만든 아트워크에는 적용되지 않습니다. 자세한 내용은 블렌더 라이센스를 참조하세요.

References

About Blender – History

Blender’s History

1988년 Ton Roosendaal은 네덜란드 애니메이션 스튜디오 NeoGeo를 공동 창립했습니다. NeoGeo는 빠르게 네덜란드 최대의 3D 애니메이션 스튜디오이자 유럽 최고의 애니메이션 하우스 중 하나가 되었습니다. NeoGeo는 다국적 전자 회사인 Philips와 같은 대기업 고객을 위해 수상 경력이 있는 작품(European Corporate Video Awards 1993 및 1995)을 제작했습니다. NeoGeo 내에서 Ton은 아트 디렉션과 내부 소프트웨어 개발을 모두 담당했습니다. 신중한 숙고 끝에 Ton은 현재 NeoGeo용 내부 3D 도구 세트가 너무 오래되고 유지 관리가 번거로워서 처음부터 다시 작성해야 한다고 결정했습니다. 1995년에 이 재작성이 시작되었고 우리 모두가 Blender로 알고 있는 3D 소프트웨어 제작이 될 운명이었습니다. NeoGeo가 계속해서 Blender를 개선하고 개선함에 따라, Ton에게는 Blender가 NeoGeo 외부의 다른 아티스트를 위한 도구로 사용될 수 있다는 것이 분명해졌습니다.

10년 뒤 Ton은 Blender의 시장을 확대하고 개발하기 위해 NeoGeo에서 분사하여 NaN(Not a Number)이라는 새로운 회사를 설립하기로 결정했습니다. NaN의 핵심에는 컴팩트한 크로스 플랫폼 3D 애플리케이션을 무료로 만들고 배포하려는 열망이 있었습니다. 당시에는 대부분의 상용 3D 애플리케이션 비용이 수천 달러에 달했기 때문에 이는 혁명적인 개념이었습니다. NaN은 일반 컴퓨팅 대중이 전문가 수준의 3D 모델링 및 애니메이션 도구를 사용할 수 있기를 바랐습니다. NaN의 비즈니스 모델에는 Blender를 중심으로 상용 제품과 서비스를 제공하는 것이 포함되었습니다. 1999년 NaN은 Blender를 보다 널리 홍보하기 위한 노력의 일환으로 첫 번째 SIGGRAPH 컨퍼런스에 참석했습니다. Blender의 첫 번째 SIGGRAPH 컨벤션은 큰 성공을 거두었으며 언론과 참석자 모두로부터 엄청난 관심을 받았습니다. 블렌더(Blender)는 히트를 쳤고 엄청난 잠재력이 확인되었습니다!

2000년 초 SIGGRAPH 컨퍼런스의 성공에 이어 NaN은 벤처 캐피털리스트로부터 450만 유로의 자금 조달을 확보했습니다. 이러한 대규모 현금 유입으로 NaN은 사업을 빠르게 확장할 수 있었습니다. 곧 NaN은 전 세계에서 50명에 달하는 직원을 고용하여 Blender를 개선하고 홍보하기 위해 노력했습니다. 2000년 여름, 블렌더 2.0이 출시되었습니다. 이 버전의 Blender에는 3D 애플리케이션에 게임 엔진 통합이 추가되었습니다. 2000년 말까지 NaN 웹사이트에 등록된 사용자 수는 250,000명을 초과했습니다.

불행하게도 NaN의 야망과 기회는 회사의 역량과 당시 시장 현실과 일치하지 않았습니다. 이러한 과도한 확장으로 인해 2001년 4월에 새로운 투자자 자금과 소규모 회사로 NaN이 다시 시작되었습니다. 6개월 후 NaN의 첫 상용 소프트웨어 제품인 Blender Publisher가 출시되었습니다. 이 제품은 대화형 웹 기반 3D 미디어라는 신흥 시장을 대상으로 했습니다. 실망스러운 판매와 계속되는 어려운 경제 상황으로 인해 새로운 투자자들은 모든 NaN 사업을 폐쇄하기로 결정했습니다. 종료시 Blender 개발 중단도 발표되었습니다. 복잡한 내부 소프트웨어 아키텍처, 미완성 기능, 비표준적인 GUI 제공 방식 등 당시 블렌더 버전에는 분명한 단점이 있었지만, 2018년 블렌더 퍼블리셔를 구매한 사용자 커뮤니티와 고객들의 열렬한 지지가 있었습니다. 이로인해 Ton은 블렌더를 무의미하게 만드는 것을 받아 들일수 없다고 판단하고 다시 재기를 꿈꾸었습니다. 큰 규모의 개발자 팀으로 회사를 다시 시작하는 것은 불가능하다는 걸 알았기 때문에 Ton Roosendaal은 2002년 3월 비영리 조직인 Blender Foundation을 설립했습니다.

블렌더 재단의 주요 목표는 블렌더를 커뮤니티 기반 오픈 소스 프로젝트로 계속 개발하고 홍보할 수 있는 방법을 찾는 것이었습니다. 2002년 7월, Ton은 NaN 투자자들이 Blender를 오픈 소스로 출시하려는 독특한 Blender Foundation 계획에 동의하도록 했습니다. “Free Blender” 캠페인은 재단이 NaN 투자자로부터 Blender 소스 코드에 대한 권리와 지적 재산권을 구입하고 이후 Blender를 오픈 소스 커뮤니티에 출시할 수 있도록 €100,000를 모금하는 것을 목표로 했습니다. 전직 NaN 직원을 포함한 열성적인 자원봉사자 그룹과 함께 “Free Blender”를 위한 모금 캠페인이 시작되었습니다. 놀랍게도 캠페인은 단 7주 만에 €100,000 목표를 달성했습니다. 2002년 10월 13일 일요일, 블렌더는 GNU GPL 조건에 따라 전 세계에 출시되었습니다. Blender 개발은 Blender의 창시자인 Ton Roosendaal이 이끄는 전 세계의 헌신적인 자원봉사자 팀에 의해 주도되어 오늘날까지 계속되고 있습니다.

Version/Revision Milestones

  • 시작!
  • 1.00 – 1994년 1월: 애니메이션 스튜디오 NeoGeo에서 블렌더를 개발 중입니다.
  • 1.23 – 1998년 1월: IrisGL 웹에 SGI 버전이 게시되었습니다.
  • 1.30 – 1998년 4월: Linux 및 FreeBSD 버전, OpenGL 및 X11로 포팅.
  • 1.3x – 1998년 6월: NaN 설립.
  • 1.4x – 1998년 9월: Sun 및 Linux 알파 버전이 출시되었습니다.
  • 1.50 – 1998년 11월: 첫 번째 매뉴얼이 출판되었습니다.
  • 1.60 – 1999년 4월: C-key(자물쇠 뒤의 새로운 기능, $95), Windows 버전 출시.
  • 1.6x – 1999년 6월: BeOS 및 PPC 버전 출시.
  • 1.80 – 2000년 6월: C 키가 종료되고 Blender 전체 프리웨어가 다시 제공됩니다.
  • 2.00 – 2000년 8월: 대화형 3D 및 실시간 엔진.
  • 2.10 – 2000년 12월: 새로운 엔진, 물리 및 Python.
  • 2.20 – 2001년 8월: 캐릭터 애니메이션 시스템.
  • 2.21 – 2001년 10월: Blender 게시자 출시.
  • 2.2x – 2001년 12월: macOS 버전.

Blender goes Open Source

2002년 10월 13일:
블렌더가 오픈 소스로 전환, 제1회 블렌더 컨퍼런스.

2.25 – 2002년 10월:
Blender Publisher가 무료로 제공되고, 코더의 놀이터인 Blender의 실험 트리가 생성됩니다.

2.26 – 2003년 2월:
최초의 진정한 오픈 소스 Blender 배포판.

2.27 – 2003년 5월:
두 번째 오픈 소스 Blender 배포판.

2.28x – 2003년 7월:
2.28x 시리즈 중 첫 번째.

2.30 – 2003년 10월:
제2회 Blender 컨퍼런스에서 발표된 2.3x UI 개선의 미리보기 배포판

2.31 – 2003년 12월:
안정적인 2.3x UI 프로젝트로 업그레이드.

2.32 – 2004년 1월:
내부 렌더링 기능이 대대적으로 개편되었습니다.

2.33 – 2004년 4월:
게임 엔진의 귀환, 주변 폐색 기능 추가, 새로운 procedural 텍스쳐 추가.

2.34 – 2004년 8월:
더욱 세심한 상호작용, LSCM UV 매핑, 기능적 YafRay 통합, 세분화된 표면의 중량으로 인한 주름표현, 램프 셰이더, OSA 전면지원 등이 있습니다.

2.35 – 2004년 11월:
개선된 또 다른 버전: 개체 후크, 곡선 변형 및 곡선 테이퍼, 입자 복제기 등.

2.36 – 2004년 12월:
안정화된 버전, 티는 안나지만 뒷단에서 많은 작업이 이루어졌던 버젼, 일반 및 변위 매핑 개선.

2.37 – 2005년 6월:
변환 도구 및 위젯, 소프트 바디, 역장, 편향, 증분 분할 표면, 투명한 그림자 및 멀티스레드 렌더링.

2.40 – 2005년 12월:
뼈대 시스템, 모양 키, 입자가 포함된 모피, 유체 및 강체를 완전히 재작업했습니다.

2.41 – 2006년 1월:
많은 수정 사항과 일부 게임 엔진 기능이 있습니다.

2.42 – 2006년 7월:
노드 릴리스, 배열 수정자, 벡터 흐림, 새로운 물리 엔진, 렌더링, 립싱크 및 기타 여러 기능이 있습니다. 이것은 Project Orange의 후속 릴리스였습니다.

2.43 – 2007년 2월:
다중 해상도 메시, 다중 레이어 UV 텍스처, 다중 레이어 이미지 및 다중 패스 렌더링 및 베이킹, 조각, 리토폴로지, 다중 추가 매트, 왜곡 및 필터 노드, 모델링 및 애니메이션 개선, 다중 브러시, 유체 입자, 프록시 개체를 사용한 향상된 페인팅 , 시퀀서 재작성 및 후반 작업 UV 텍스처링.

2.44 – 2007년 5월:
두 가지 새로운 수정자와 64비트 OS 지원을 다시 활성화하는 것 외에도 유기물과 부드러운 물체의 표면 아래에서 빛의 산란을 시뮬레이션하는 표면 아래 산란이 추가되었다는 큰 소식이 있었습니다.

2.45 – 2007년 9월:
일부 성능 문제가 해결된 심각한 버그 수정.

2.46 – 2008년 5월:
Peach 릴리스는 머리카락과 털, 새로운 파티클 시스템, 향상된 이미지 탐색, 천, 원활하고 방해가 되지 않는 물리 캐시, 반사, AO 및 렌더링 개선 사항을 제공하기 위한 개선 사항을 제공하는 70명 이상의 개발자의 엄청난 노력의 결과입니다. 렌더 베이킹, 근육 등을 위한 메시 변형 수정자, 뼈대 도구 및 드로잉, 스키닝, 제약 조건 및 다채로운 액션 편집기 등을 통한 향상된 애니메이션 지원. 프로젝트 피치(Project Peach)의 결과가 담겨있습니다.

2.47 – 2008년 8월:
버그픽스 릴리스.

2.48 – 2008년 10월:
Apricot 릴리스, 멋진 GLSL 셰이더, 조명 및 GE 개선 사항, 스냅, 하늘 시뮬레이터, Shrinkwrap 수정자 및 Python 편집 개선 사항. 여기에는 Project Apricot 결과가 포함되어 있습니다.

2.49 – 2009년 6월:
노드 기반 텍스처, 뼈대 스케치(Etch-a-Ton이라고 함), 부울 메시 작업 개선, JPEG2000 지원, 이미지를 모델로 직접 전송하기 위한 프로젝션 페인팅 및 중요한 Python 스크립트 카탈로그. GE 개선 사항에는 게임 내에서 영화를 재생할 수 있는 비디오 텍스처, Bullet 물리 엔진 업그레이드, 돔(어안) 렌더링 및 더 많은 API GE 호출이 포함되었습니다.

Blender 2.5x – The Recode!

2.5x – 2009년부터 2011년 8월까지:
이 시리즈는 4개의 사전 버전(2009년 11월 Alpha 0부터 2010년 7월 베타까지)과 3개의 안정 버전(2.57 – 2011년 4월부터 2.59 – 2011년 8월)을 출시했습니다. 새로운 기능을 갖춘 소프트웨어의 전체 리팩터링, 내부 창 관리자 및 이벤트/도구/데이터 처리 시스템의 재설계, 새로운 Python API를 갖춘 가장 중요한 개발 프로젝트 중 하나였습니다. 이 프로젝트의 최종 버전은 2011년 8월의 Blender 2.59였습니다.

Blender 2.6x to 2.7x – Improvements & Stabilizing

2.60 – 2011년 10월:
UI 국제화, 애니메이션 시스템 및 GE 개선, 정점 가중치 그룹 수정자, 3D 오디오 및 비디오, 버그 수정.

2.61 – 2011년 12월:
Cycles 렌더러가 트렁크에 추가되었고, 카메라 추적기가 추가되었으며, 메쉬 접촉/근사로 텍스처를 수정하기 위한 동적 페인트, 바다와 거품을 시뮬레이션하기 위한 Ocean 수정자, 새로운 추가 기능, 버그 수정 및 Python에 추가된 더 많은 확장이 있습니다. API.

2.62 – 2012년 2월:
부울 연산을 개선하기 위해 Carve 라이브러리가 추가되었고, 객체 추적에 대한 지원이 추가되었으며, Remesh 수정자가 추가되었으며, GE의 많은 개선 사항, Python API의 행렬 및 벡터가 개선되었으며, 새로운 추가 기능과 많은 버그 수정이 이루어졌습니다.

2.63 – 2012년 4월:
Bmesh는 n면 다각형, 조각 숨기기, Cycles용 파노라마 카메라, 미러 볼 환경 텍스처 및 부동 정밀 텍스처, 렌더링 레이어 마스크 레이어, 주변 폐색 및 배경 이미지의 뷰포트 표시 및 렌더링 레이어를 완벽하게 지원하는 트렁크와 병합되었습니다. . 새로운 가져오기 및 내보내기 추가 기능이 추가되었으며 150개의 버그가 수정되었습니다.

2.64 – 2012년 10월:
향상된 모션 트래커, OpenColorIO, 사이클 개선, 시퀀서 개선, 더 나은 메시 도구(삽입 및 베벨 개선), 새로운 키잉 노드, 조각 마스킹, Collada 개선, 새로운 스킨 수정자, 새로운 합성과 함께 마스크 편집기가 추가되었습니다. 노드 백엔드 및 많은 버그 수정.

2.65 – 2012년 12월:
화재 및 연기 개선, 사이클용 이방성 셰이더, 수정자 개선, 베벨 도구에는 이제 반올림, 새로운 추가 기능 및 200개 이상의 버그 수정이 포함됩니다.

2.66 – 2013년 2월:
동적 토폴로지, 강체 시뮬레이션, UI 및 유용성 개선(망막 디스플레이 지원 포함), 이제 Cycles에서 머리카락을 지원하고, 베벨 도구에서 개별 정점 베벨을 지원하고, 새로운 메시 캐시 수정자와 새로운 UV 워프 수정자, 새로운 SPH 입자 유체 솔버를 지원합니다. 250개 이상의 버그 수정.

2.67 – 2013년 5월:
자유형 추가, 페인트 시스템 개선, Cycles용 표면 아래 산란, 모션 추적기의 Ceres 라이브러리, 새로운 사용자 정의 Python 노드, 새로운 메시 모델링 도구, UTF-8 텍스트에 대한 향상된 지원 및 텍스트 편집기 개선, 3D 인쇄를 위한 새로운 추가 기능 , 260개 이상의 버그 수정.

2.68 – 2013년 7월:
새롭고 향상된 모델링 도구, 3개의 새로운 Cycles 노드, 모션 추적기의 대폭 개선, 보안상의 이유로 파일을 로드할 때 Python 스크립트 및 드라이버가 기본적으로 비활성화되며 280개 이상의 버그 수정이 이루어졌습니다.

2.69 – 2013년 10월:
더 많은 모델링 도구, Cycles의 여러 영역 개선, 평면 추적이 모션 추적기에 추가되고 FBX 가져오기/내보내기에 대한 지원이 향상되었으며 270개 이상의 버그가 수정되었습니다.

2.70 – 2014년 3월:
Cycles는 CPU에 대한 기본 체적 지원, 모션 추적기의 추가 개선, 두 가지 새로운 모델링 수정자, 일부 UI 일관성 개선 및 560개 이상의 버그 수정을 제공합니다.

2.71 – 2014년 6월:
변형 모션 블러 및 화재/연기 지원이 Cycles에 추가되었으며 이제 UI 팝업을 드래그할 수 있습니다. 조각 모드에 대한 성능 최적화, 애니메이션을 위한 새로운 보간 유형, GE에 대한 많은 개선 사항 및 400개 이상의 버그 수정이 있습니다.

2.72 – 2014년 10월:
Cycles는 GPU에서 볼륨 및 SSS 지원을 받고, 파이 메뉴가 추가되고 도구 설명이 크게 개선되었으며, 교차점 모델링 도구가 추가되고, Compositor를 위한 새로운 Sun Beam 노드가 추가되었으며, 이제 Freestyle이 Cycles와 함께 작동하고, 텍스처 페인팅 작업 흐름이 개선되었으며, 220개 이상 버그 수정.

2.73 – 2015년 1월:
Cycles는 향상된 체적 지원, Grease Pencil의 주요 업그레이드, Windows의 IME(입력 방식 편집기) 및 페인팅, Freestyle, Sequencer 및 추가 기능에 대한 전반적인 개선을 제공합니다.

2.74 – 2015년 3월:
사용자 정의 법선, 뷰포트 합성 및 헤어 역학 개선을 지원합니다.

2.75 – 2015년 7월:
통합된 스테레오/다중 뷰 파이프라인, Smooth Corrective 수정자 및 새로운 개발 종속성 그래프.

2.76 – 2015년 11월:
Pixar OpenSubdiv 지원, 뷰포트 및 파일 브라우저 성능 향상, 노드 자동 오프셋 및 시퀀서용 텍스트 효과 스트립.

2.77 – 2016년 3월:
연기/체적 시뮬레이션 캐싱을 위한 OpenVDB 지원, 향상된 Cycles 지하 산란, Grease Pencil 스트로크 조각 및 향상된 작업 흐름, 누락 및 삭제된 데이터 블록을 관리하기 위한 재작업된 라이브러리 처리.

2.78 – 2016년 9월:
VR용 구형 스테레오 이미지에 대한 Cycles 지원, Grease Pencil은 다른 2D 드로잉 소프트웨어와 더 유사하게 작동하고, Alembic 가져오기 및 내보내기 지원, 더 쉽고 간단한 리깅을 위한 Bendy Bones 개선이 이루어졌습니다.

2.79 – 2017년 9월:
새로운 Cycles 기능: Denoising, Shadow catcher 및 새로운 Principled 셰이더. Grease Pencil 및 Alembic에 다른 개선 사항이 적용되었습니다. 애플리케이션 템플릿에 대한 지원도 추가되었습니다.

Blender 2.8 – Revamped UI

2.80 – 2019년 7월:
보다 쉬운 탐색을 위해 완전히 새롭게 디자인된 UI; 향상된 뷰포트, 기즈모 및 도구. EEVEE를 통해 새로운 물리 기반 실시간 렌더링 엔진이 생성되었습니다. Grease Pencil은 대대적인 점검을 거쳐 이제 완전한 2D 드로잉 및 애니메이션 시스템이 되었습니다. 이전 레이어를 대체하는 컬렉션은 개체를 구성하는 강력한 방법입니다. 기타 개선 사항: 주기, 모델링, 애니메이션, 가져오기/내보내기, 종속성 그래프.

2.81 – 2019년 11월:
개선된 조각 도구, Cycles OptiX 가속 렌더링, 노이즈 제거, 다양한 EEVEE 개선, 라이브러리 재정의, UI 개선 등.

2.82 – 2020년 2월:
UDIM 및 USD 지원, 유체 및 연기 시뮬레이션을 위한 Mantaflow, AI 노이즈 제거, Grease Pencil 개선 등.

2.83 – 2020년 6월:
3D 뷰포트 가상 현실 장면 검사, 새로운 볼륨 개체 유형, Cycles 적응형 샘플링, Cycles 뷰포트 노이즈 제거, 조각 개선 등.

Blender 2.9 – Refining 2.8

2.90 – 2020년 8월:
개선된 하늘 질감, EEVEE 모션 블러, 조각 개선, 개선된 수정자 UI, 개선된 모델링 도구 및 Cycles의 더 빠른 모션 블러.

2.91 – 2020년 11월:
아웃라이너 개선, 속성 검색, 개선된 메시 부울 연산, 애니메이션 곡선, 볼륨 객체 및 디스플레이 개선, 더욱 세련된 조각 도구.

2.92 – 2021년 2월:
지오메트리 노드, 기본 추가 도구, 조각 개선, Grease Pencil 곡선 편집, Cycles 색상 속성 베이킹, APIC 유체 시뮬레이션, 비디오 시퀀서 개선 등.

2.93 – 2021년 6월:
새로운 지오메트리 노드, 조각 개선 사항, 기타 개선 사항과 함께 그리스 연필 라인 아트 수정자, EEVEE 렌더 엔진의 향상된 DOF, 재설계된 Cryptomatte 워크플로우 등이 포함됩니다.

Blender 3.0 – Optimizing Performance

3.0 – 2021년 12월
자산 브라우저 추가, Cycles X, EEVEE 속성, 새로운 지오메트리 노드, 애니메이션 업데이트, Grease Pencil 라인 아트 개선, 포즈 라이브러리, 2~8배 빠른 Open Image Denoising, Linux에서 AMD에 대한 추가 지원.

3.1 – 2022년 3월
주요 포인트 클라우드 개선, Cycles Apple Metal GPU 지원, Subdivision GPU 지원, 이미지 편집기에서 더 큰 이미지 처리, 지오메트리 노드의 주요 성능 향상, 지오메트리 노드에 대한 상황 인식 검색.

3.2 – 2022년 6월
사이클용 조명 그룹, 진정한 그림자 화선, 볼륨 모션 블러, GLTF 개선, Linux에서의 AMD GPU 렌더링, 조각 모드 페인팅, WEBp 이미지 지원.

3.3 – 2022년 9월
새로운 머리카락 개체, 절차적 UV 노드, 라인 아트 그림자 및 윤곽선, oneAPI를 통한 Intel GPU 렌더링 지원, 라이브러리 재정의 개선.

3.4 – 2022년 12월
사이클 경로 안내, 조각 자동 마스킹 개선, 더 많은 지오메트리 노드, UV 편집 개선 및 Linux에서의 Wayland 지원.

3.5 – 2023년 3월
새로운 생성 헤어 자산, 조각용 벡터 변위 맵, 뷰포트 합성기 및 Cycle의 라이트 트리.

References

About Blender – Introduction

Hello!

안녕하세요. Blender에 오신 여러분을 환영합니다. Blender는 무료 오픈소스 3D 제작 툴입니다.

Blender와 함께 하시면 3D 이미지를 만드실수도 있고, 만드신 이미지로 애니메이션을 구현하실 수도 있습니다. 이 툴을 가지고 비디오영상을 편집하실 수도 있구요, 특히 개인이나 소규모 스튜디오에서 일관된 결과물을 세련되게 개발할 수 있게 도움을 주는 툴입니다.

Blender는 다양한 플랫폼에서 설치가 가능한데요, 리눅스나 맥OS그리고 윈도우에서도 잘 돌아갑니다. 심지어 다른 3D툴들에 비해 메모리를 적게 잡아먹기까지 합니다. 인터페이스로는 OpenGL을 사용하여 다양한 하드웨어나 서로 다른 플랫폼에서도 일관된 사용자경험을 할수 있게 해드립니다.

Who uses Blender?

누가 Blender를 이용하느냐? 블렌더는요 미디어 영상제작에 매우 많은 분야에서 폭넓게 활용되어 있고 있는데요. 전문가들, 취미로 하시는 분들 그리고 여러나라의 스튜디오에서 저희 제품을 사용하고 있습니다. 이 분들은 애니메이션을 제작하기도 하시고, 게임 캐릭터나 공간을 만들기도 하며, 그래픽의 움직임을 구현할때도, 심지어 테레비젼 프로그램에도 활용되고, 예술분야에서도 스토리보드를 짤때고 광고, 필름등 다양한 분야에서 매우 활발하게 활용이 되고 있습니다.

블렌더를 활용한 더 많은 웹사이트를 보시고 싶으시면 User Stories page를 참고해주세요.

Key Features

  • 블렌더는 모델링, 렌더링, 애니메이션 및 리깅, 비디오 편집, VFX, 합성, 텍스처링 및 다양한 유형의 시뮬레이션을 포함한 광범위한 필수 도구를 제공하는 완전히 통합된 3D컨텐츠 제작 툴입니다.
  • 모든 주요 플랫폼에서 통일된 OpenGL GUI를 갖춘 크로스 플랫폼입니다(Python 스크립트로 사용자 정의 가능).
  • 고품질 3D 아키텍처를 갖추고 있어 빠르고 효율적인 제작이 가능합니다.
  • 적극적인 커뮤니티 지원을 자랑합니다. 광범위한 사이트 목록은 blender.org/community를 참조하세요.
  • 블렌더는 별도로 사용이 가능한 작은 실행파일들도 함께 제공합니다.


여기에서 최신 버전의 블렌더를 다운로드할 수 있습니다.

렌더링된 이미지가 후처리되고 있습니다.

블렌더를 사용하면 광범위한 작업을 수행할 수 있으며 처음 기본 사항을 파악하려고 할 때는 살짝 어렵게 느껴질 수 있습니다. 그러나 약간의 동기 부여와 올바른 학습 자료가 있으면 몇 시간의 연습 후에 Blender에 익숙해지는 것이 가능합니다.

이 매뉴얼은 좋은 시작이지만 참고용으로 더 많이 사용됩니다. 전문 웹사이트에서 제공하는 온라인 비디오 튜토리얼도 많이 있습니다.

블렌더가 많은 것들을 할수 있도록 가능하게 하지만 그래도 여전히 하나의 도구에 불과합니다. 위대한 예술가는 버튼을 누르거나 브러시를 조작하여 걸작을 만드는 것이 아니라 인체 해부학, 구성, 조명, 애니메이션 원리 등과 같은 주제를 배우고 실습함으로써 걸작을 탄생시킵니다.

Blender와 같은 3D 제작 소프트웨어에는 기본 기술과 관련된 기술적 복잡성과 전문 용어가 추가되었습니다. UV 맵, 재질, 셰이더, 메쉬 및 “subdivs”와 같은 용어는 디지털 아티스트의 미디어이며, 이를 이해하면 Blender를 최대한으로 활용하는 데 도움이 됩니다.

따라서 이 매뉴얼을 계속 읽고, 블렌더의 훌륭한 도구를 배우고, 다른 예술 및 기술 분야에 마음을 열어두십시오. 그러면 당신도 훌륭한 예술가가 될 수 있습니다.

References

The Python Tutorial #5 – Control Flow

More Control Flow Tools

이전 시간에 마지막 예제에서 피보나치 수열을 구현하면서 while반복문을 써봤는데요, 이번 챕터에서는 그밖에 파이썬에서 제공하는 몇가지 유용한 명령어들을 더 배워볼거에요.

if Statements

아마도 if문은 어느 언어에서나 가장 잘 알려진 명령어가 아닐까 생각이 되어집니다. 아래 예제를 보시면요,

>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
...     x = 0
...     print('Negative changed to zero')
... elif x == 0:
...     print('Zero')
... elif x == 1:
...     print('Single')
... else:
...     print('More')
... 
More

elifelse는 생략해도 됩니다. elif는 else if의 줄임말인데 만약에 if…elif…elif…이렇게 elif를 여러번 써야하는 경우에는 다른 언어는 switch, case를 사용하는데요. 파이썬에서는 match, case를 이용하여 구현하실수 있습니다.

>>> a = 1
>>> match a:
...   case 0:
...     print('영')
...   case 1:
...     print('하나')
...   case 2:
...     print('둘')
...
하나

for Statements

파이썬에서의 for문은 C나 파스칼에서 사용되어지는 것과는 조금 다릅니다. 보통 파스칼에서는 산술적으로 숫자를 비교하면서 반복을 하게 되고, C에서는 반복 단계나 정지 조건을 주어 for문을 정의합니다. 하지만 파이썬에서는 list나 문자열같은 시퀀스를 이용해서 해당 시퀀스의 아이템을 하나씩 방문하는 식으로 반복문을 돌리게 됩니다. 아래 예제는 for문을 사용하여 문자열의 길이를 재는 코드입니다.

>>> words = ['cat', 'window', 'defenestrate']
>>> for w in words:
...     print(w, len(w))
...
cat 3
window 6
defenestrate 12

말씀드렸다시피 파이썬에서는 for문의 조건문으로 list에 들어갑니다. 그런데 for문 안에서 해당 list의 내용을 수정하거나 길이를 변경한다면 for문의 조건이 되기에는 명확하지 않은 구성이 되어버립니다. 그렇게 코딩을 할수도 있긴 하겠죠 하지만 for문 안에서 조건이 바뀔 수 있다는 걸 염두해 두어야한다면 실제로 구현해야하는 로직에 촛점을 맞추기가 힘들어 질수도 있기때문에 추천하지 않습니다.

>>> users = {'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'}
>>> for user, status in users.copy().items():
...     if status == 'inactive':
...         del users[user]
...
>>> users
{'Hans': 'active', '景太郎': 'active'}

그래서 list의 내용을 바꿔서 저장해야하는 경우에는 보통 새로운 list를 만들어서 저장하거나 기존 list를 복사해서 결과를 따로 보관합니다.

>>> users = {'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'}
>>> active_users = {}
>>> for user, status in users.items():
...     if status == 'active':
...         active_users[user] = status
...
>>> users
{'Hans': 'active', 'Éléonore': 'inactive', '景太郎': 'active'}
>>> active_users
{'Hans': 'active', '景太郎': 'active'}

그러면 위의 예제와 같이 for문의 조건으로 사용하는 users는 원래 그대로의 모습을 간직할 수 있고, active_users에서 현재 활동중인 회원들만 추려서 볼수 있게 됩니다.

The range() Function

만약 list없이 기존의 C나 파스칼 처럼 숫자로 연산처리를 해서 for문을 돌리고 싶으실때는 파이썬의 빌트인 함수인 range()를 사용하시면 됩니다.

>>> for i in range(5):
...     print(i)
...
0
1
2
3
4

여기서 넘겨받은 숫자 5는 for문의 반복문에 포함되지 않습니다. range(5)는 5개의 숫자를 출력하지만 range()가 넘겨주는 숫자는 기본적으로 0부터 시작되기 때문에 넘겨받은 인자 5는 결과에 포함되지 않습니다. 만약에 숫자를 0부터 시작하고 싶지 않다면 시작할 숫자를 첫번째 인자에 명시하고 두번째 인자에 총 반복할 횟수를 적어주시면 됩니다. range는 아래와 같이 list에 저장할 수도 있는데요, 시작하는 숫자와 총 반복할 횟수 및 반복할 숫자의 간격을 인자로 넘겨주어 다양한 숫자의 list를 만들어 반복문에 사용할 수 있습니다.

>>> list(range(5, 10))
[5, 6, 7, 8, 9]
>>> list(range(0, 10, 3))
[0, 3, 6, 9]
>>> list(range(-10, -100, -30))
[-10, -40, -70]

만약 시퀀스의 인덱스로 반복문을 돌리고 싶으시면 range()len()을 같이 써서 아래와 같이 구현하실 수 있습니다.

>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
...     print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb

대부분의 경우에 배열을 반복할때 enumerate()를 사용하시면 굉장히 편리합니다.

>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1))
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

enumerate()에 list를 인자로 주어 반복문의 조건으로 사용하면 인덱스번호와 해당 인덱스의 값을 함께 가져올수 있어 매우 유용합니다.

>>> for i, v in enumerate(['tic', 'tac', 'toe']):
...     print(i, v)
...
0 tic
1 tac
2 toe

아래는 Looping Techniques에서 소개한 반복문에 사용될 수 있는 테크닉들입니다.

items()

>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
...     print(k, v)
...
gallahad the pure
robin the brave

zip()

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
...     print('What is your {0}?  It is {1}.'.format(q, a))
...
What is your name?  It is lancelot.
What is your quest?  It is the holy grail.
What is your favorite color?  It is blue.

reversed()

>>> for i in reversed(range(1, 10, 2)):
...     print(i)
...
9
7
5
3
1

sorted()

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for i in sorted(basket):
...     print(i)
...
apple
apple
banana
orange
orange
pear

set() & sorted()

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear

만약 파이썬 인터프리터에 range()만 딸랑 실행을 하면 조금 이상한 결과를 보게 될겁니다.

>>> range(10)
range(0, 10)

마치 아무것도 실행하지 않은 것처럼 말이죠. 많은 경우에 range()는 list타입의 데이타를 반환하는 것처럼 행동합니다. 하지만 사실 range는 list를 반환하지 않습니다. 왜냐면 실제 list를 반환하려면 list를 어딘가에 저장해야하는데 그렇게 한다면 너무 많은 공간을 써야하는 경우가 생기기 때문입니다. 그래서 range()는 필요한 list를 만들어 낼수 있는 정보가 들은 Object를 반환하고 for문은 그걸 이미 알고 있기 때문에 그 Object를 자동으로 list로 변환한뒤 반복문을 처리하게 됩니다.

요약하자면 range()가 반환하는 Object는 list를 처리할 수 있는 거의 대부분의 함수나 명령문에서 list처럼 처리를 해줍니다. for문에서 그러하듯이 sum()도 list를 받아서 해당 배열의 값들을 전부 더한 결과를 반환하는데 마찬가지로 range()로 생성된 숫자들도 list로 변환하지 않아도 다 합해서 결과를 반환합니다.

>>> a = [1, 2, 3, 4]
>>> sum (a)
10
>>> sum(range(1, 5))
10

나중에 Data Structures를 설명하는 챕터에서 list()에 대해서 좀더 자세하게 설명드리도록 하겠습니다.

break and continue Statements, and else Clause on Loops

break문은 for문이나 while문의 반복을 종료합니다. 반복문이 다중으로 겹쳐있을때는 break문이 들어가 있는 해당 반복문만 종료하고 그 반복문 바깥쪽에 선언된 반복문은 계속해서 실행합니다.

for문이나 while문은 else문을 포함할 수 있습니다.

  • for문에서 else가 실행되는 시점은 마지막 for문을 다 돌고 나서 for문을 빠져나가기 직전에 else에 기술된 코드를 실행하고 나갑니다.
  • while문에서는 while의 조건문이 false가 되는 시점에서 else안의 내용을 실행합니다.
  • for와 while 두개 다 break에 의해서 반복문이 종료된다면 else는 실행하지 않고 그냥 반복문을 종료합니다.

아래의 소수찾기 코드가 else를 실행하는 좋은 예가 될것같은데 함께 보시죠.

>>> for n in range(2, 10):
...     for x in range(2, n):
...         if n % x == 0:
...             print(n, 'equals', x, '*', n//x)
...             break
...     else:
...         # loop fell through without finding a factor
...         print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3

위의 예제는 숫자 2에서 부터 9까지 돌면서 해당 숫자가 소수인지를 판별하는 코드입니다. 소수인지를 판별하는 방법은 해당 숫자로 나누어 떨어지는 수가 있으면 소수가 아닌게 되어서 해당 숫자 보다 작은 수로 나누어 떨어지는 값이 있는 지를 반복적으로 확인하고 만약 나누어 떨어지는 수가 있으면 소수가 아니라고 출력하고 break를 해서 else를 거치지 않고 다음 숫자로 넘어갑니다. 반대로 반복문을 다 돌도록 나누어 떨어지는 수를 하나도 발견하지 못했다면 break당하지 않고 반복문을 종료하게 되어서 이때는 else를 거치고 갑니다. else에 들어가는 숫자는 소수라는 의미니까 else에서 해당 숫자가 소수라는 것을 출력하고 다음 숫자로 넘어갑니다.

위와 같이 for문과 else절이 함께 사용되면 그 else절은 if문에서의 else절이라기 보다 try문에서의 else절이라고 생각하면 의미가 좀 더 가깝습니다. try문의 else절은 예외가 발생하지 않았을때 실행이 되는 것과 마찬가지로, 반복문의 break가 발생하지 않았을때 else절이 실행되는 것과 일맥 상통합니다. try문과 예외처리에 대한 자세한 사항은 Handling Exceptions를 참고해주세요.

파이썬의 continue문은 C언어에서 보고 따라 만든건데요. 반복문 안에서 continue를 만나면 다음 숫자로 바로 넘어가라는 뜻입니다.

>>> for num in range(2, 10):
...     if num % 2 == 0:
...         print("Found an even number", num)
...         continue
...     print("Found an odd number", num)
...
Found an even number 2
Found an odd number 3
Found an even number 4
Found an odd number 5
Found an even number 6
Found an odd number 7
Found an even number 8
Found an odd number 9

pass Statements

pass문은 “아무것도 안합니다”. pass는 문법적으로 필요한 부분인데 아무런 액션도 취해서는 안되는 부분을 프로그램 할때 사용됩니다.

>>> while True:
...     pass  # 키보드에서 인터럽트 키(Ctrl+C)를 칠때까지 기다립니다
...



^CTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyboardInterrupt

중간에 아무리 엔터를 쳐도 프롬프트가 나타나지 않고 계속 빈 줄을 보여주면서 기다리다가 Ctrl+C로 인터럽트를 하면 그제서야 상황이 종료가 됩니다. 보통 pass는 비어있는 클래스를 선언할때 주로 사용됩니다.

>>> class MyEmptyClass:
...     pass
...

pass는 place-holder함수를 구현할때나 좀더 추상적인 단계에서 코딩을 할때 필요한 구조를 만들고 구체적인 내용은 나중에 생각하자는 마음으로 일단 필요한 함수들을 선언한 뒤에 딱히 내용이 없으면 에러가 나니까 안에다가 pass를 넣어 문법적으로 문제가 없도록 일단 만들어 놓는 것입니다. place-holder함수는 객체지향 코드시 클래스를 정의할때 클래스 안에 함수명만 일단 정의해 놓고 나중에 구현할때 내용을 채워서 재정의하라는 가이드라인같은 건데요. 이때 함수를 정의할때 pass만 들어가있는 빈 함수를 바로 place-holder함수라고 합니다.

>>> def initlog(*args):
...     pass   # Remember to implement this!
...

match Statements

match문은 표현식을 받아서 값과 비교하고 같은 값을 가지는 case블락에 들어가서 해당 코드를 실행합니다. 파이썬에서의 match문은 근본적으로 C언어나 자바, 자바스크립트(기타 많은 다른 언어들)의 switch문과 같습니다. 하지만 패턴이 매칭되는 매커니즘은 Rust나 Haskell과 좀더 유사합니다. 오직 첫번째로 매칭된 패턴만이 실행되고 또한 값에서 구성요소(시퀀스 요소 또는 객체 속성)를 변수로 추출할 수도 있습니다.

하나 이상의 값을 비교하는 가장 심플한 형태의 코드는 바로 match로 구현할 수 있습니다.

def http_error(status):
    match status:
        case 400:
            return "Bad request"
        case 404:
            return "Not found"
        case 418:
            return "I'm a teapot"
        case _:
            return "Something's wrong with the internet"

마지막 case절을 보면 _라는 변수가 있습니다. 이것은 와일드카드인데 매치되는 값이 하나도 없을때 _로 정의된 case절에 매치가 되어 해당 블록의 코드를 실행합니다.

여러개의 값을 하나의 패턴으로 만들고자할때 |(“or”)를 사용하여 아래와 같이 만들 수 있습니다.

case 401 | 403 | 404:
    return "Not allowed"

case절의 패턴들은 변수와 섞어서 실행할때 마다 다른 패턴이 되도록 코딩할 수 도 있는데 예를 들면 다음과 같습니다.

# (x, y)는 집합입니다
match point:
    case (0, 0):
        print("Origin")
    case (0, y):
        print(f"Y={y}")
    case (x, 0):
        print(f"X={x}")
    case (x, y):
        print(f"X={x}, Y={y}")
    case _:
        raise ValueError("Not a point")

위의 예제는 좀더 자세히 연구해봐야합니다. 첫번째 패턴은 두개의 고정된 값을 가지며 위에 표시된 리터럴 패턴의 연장선으로 생각할 수 있습니다. 하지만 그 다음 두 패턴은 리터럴과 변수가 섞여 있습니다. 그리고 변수는 비교값 point에서 가져온 값과 바인딩합니다. 네번째 패턴은 2개의 변수를 가지고 값을 비교하는데 이를 표현식으로 바꿔보면 (x, y) = point과 같습니다.

만약 여러분이 데이타를 구조화 하기 위해 클래스를 사용하신다면, 객체를 생성할때 생성자에 인자를 넘겨주는 것처럼 클래스이름 뒤에 각 변수를 나열하여 사용할 수도 있습니다. 다만 이 경우에는 속성값을 갖다 변수에 넣을 수 있습니다.

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

def where_is(point):
    match point:
        case Point(x=0, y=0):
            print("Origin")
        case Point(x=0, y=y):
            print(f"Y={y}")
        case Point(x=x, y=0):
            print(f"X={x}")
        case Point():
            print("Somewhere else")
        case _:
            print("Not a point")

인자로 넘길때는 변수명을 적어주어도 되고, 그냥 값만 넘길 경우에는 인자의 순서에 따라 어떤 값이 어느 변수에 들어갈지가 결정이 됩니다. 아래의 예제처럼 변수명과 값을 둘다 넘겨줄 경우에는 순서가 뒤바뀌어도 상관없습니다.

Point(1, var)
Point(1, y=var)
Point(x=1, y=var)
Point(y=var, x=1)

case절에 들어가는 패턴은 아래의 예제와 같이 다중으로 조건을 설정할 수 있습니다.

class Point:
    __match_args__ = ('x', 'y')
    def __init__(self, x, y):
        self.x = x
        self.y = y

match points:
    case []:
        print("No points")
    case [Point(0, 0)]:
        print("The origin")
    case [Point(x, y)]:
        print(f"Single point {x}, {y}")
    case [Point(0, y1), Point(0, y2)]:
        print(f"Two on the Y axis at {y1}, {y2}")
    case _:
        print("Something else")

case절에 if문을 추가할 수도 있습니다. 만약 case절의 패턴이 True라도 if문의 조건이 False이면 match문은 다음 case절로 넘어갑니다.

match point:
    case Point(x, y) if x == y:
        print(f"Y=X at {x}")
    case Point(x, y):
        print(f"Not on the diagonal")

match문에 관한 몇가지 주요기능:

  • Like unpacking assignments, tuple and list patterns have exactly the same meaning and actually match arbitrary sequences. An important exception is that they don’t match iterators or strings.
  • Sequence patterns support extended unpacking: [x, y, *rest] and (x, y, *rest) work similar to unpacking assignments. The name after * may also be _, so (x, y, *_) matches a sequence of at least two items without binding the remaining items.
  • Mapping patterns: {"bandwidth": b, "latency": l} captures the "bandwidth" and "latency" values from a dictionary. Unlike sequence patterns, extra keys are ignored. An unpacking like **rest is also supported. (But **_ would be redundant, so it is not allowed.)
  • Subpatterns may be captured using the as keyword:
    case (Point(x1, y1), Point(x2, y2) as p2): ...
    will capture the second element of the input as p2 (as long as the input is a sequence of two points)
  • Most literals are compared by equality, however the singletons TrueFalse and None are compared by identity.
  • Patterns may use named constants. These must be dotted names to prevent them from being interpreted as capture variable:
from enum import Enum
class Color(Enum):
    RED = 'red'
    GREEN = 'green'
    BLUE = 'blue'

color = Color(input("Enter your choice of 'red', 'blue' or 'green': "))

match color:
    case Color.RED:
        print("I see red!")
    case Color.GREEN:
        print("Grass is green")
    case Color.BLUE:
        print("I'm feeling the blues :(")

더욱 자세한 예제와 설명을 원하시면 PEP 636를 참고 하세요.

Defining Functions

우리는 임의의 바운더리안에서 피보나치 수열을 생성하는 함수를 만들 수 있습니다.

>>> def fib(n):    # write Fibonacci series up to n
...     """Print a Fibonacci series up to n."""
...     a, b = 0, 1
...     while a < n:
...         print(a, end=' ')
...         a, b = b, a+b
...     print()
...
>>> # Now call the function we just defined:
>>> fib(2000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

예약어 def는 함수를 정의하겠다는 명령어입니다. 곧이어 def뒤로는 함수명이 뒤따르고, 괄호 안에 함수에 필요한 매개변수들이 나열됩니다. 다음 줄에서 실제 함수의 몸통 부분이 정의되고 그 내용은 반드시 들여쓰기가 되어있어야합니다.

함수의 몸통부분에 첫번째 줄에는 함수에 대한 설명을 적어넣을 수 있는 문자열이 들어가는데 함수명이 정의 되어 있는 바로 다음줄에 문자열이 나오면 함수에 대한 설명, 즉 주석정도로 인식하고 코드로 인식하지 않습니다. 함수설명은 필수 사항은 아니며, 함수명 정의하고 다음 줄에 문자열이 바로 나오지 않으면 함수 설명이 없는 것으로 간주하고 그냥 넘어갑니다. 근데 함수설명을 달아놓는 것은 좋은 코딩습관입니다. 왠만하면 항상 함수설명을 달아 놓도록 합니다. 사소하지만 습관이 들면 정말 좋은 코딩 습관이 될것입니다.

함수를 실행하면요 함수 안에서 변수들이 저장되는데요, 이때 심볼 테이블이라고 불리는 어떤 테이블형태의 저장공간을 만들어서 거기다가 지역변수들을 저장합니다. 반대로 변수를 참조할때는 먼저 지역 심볼 테이블을 찾고 그 다음에 어미 함수의 지역 심볼 테이블을 찾고 더이상 호출한 어미 함수가 없는 경우 전역 심볼테이블에서 해당 변수명을 찾습니다. 만약 거기서도 찾지 못한다면 파이썬에 내장되어 있는 변수명을 참습니다. 기본적으로는 전역변수와 함수를 호출한 어미 함수의 변수들은 자식 함수 안에서 바로 값을 할당할 수 없고 그저 참조만 할 수 있습니다. 다만, 함수내에서 전역변수에할당하고자 할때 변수명 앞에 global이라고 명시하면 전역변수라도 함수내에서 할당이 가능하고요, nonlocal이라고 명시하면 호출한 어미함수의 변수값도 변경이 가능합니다.

함수가 호출되면 함수명과 함께 전달된 매개변수들은 이 심볼테이블에 저장이 됩니다. 그 말은 함수와 함께 전달된 매개변수는 그 값이 복사되어 지역 심볼테이블에 저장되기 때문에 함수 내에서 아무리 그 값을 변경해도 원래 호출할때 사용했던 변수값에는 아무런 영향을 끼치지 못합니다.

근데 변수를 선언하면 사실 그게 Object인건 아시나요? 파이썬에서 모든 것들은 전부 Object입니다. 심지어 변수까지도요. 그리고 변수값은 해당 객체 안에 내부 변수로 저장이 되어있는 거라서 사실 변수명이 가리키고 있는것은 그 값이 아니라 객체의 주소에요. 다만, 그 객체에 접근하면 저장한 값을 반환하도록 설계된 클래스였던거죠. 그러니까 다시 말하면 매개변수를 넘기면 지역함수 안에 객체자체를 새롭게 생성한다는 말이에요.

함수가 호출되면 그 함수만의 심볼테이블이 생성되고, 심지어 재귀적으로 해당 함수를 호출해도 그것은 다 다른 호출로 인식이 되어 호출될 때마다 새로운 심볼테이블을 생성하여 함수 내에서 선언한 변수들과 인자로 전달받은 매개변수들을 그곳에 저장합니다.

함수를 정의하면요, 그 함수 이름과 함수에 정의된 내용 부분인 Object도 마찬가지로 심볼 테이블에 저장됩니다. 인터프리터는 해당 함수명이 가리키는 Object를 사용자 정의 함수로 인식하고요. 해당 함수명을 다른 함수명에 할당하면 새로 할당된 함수명으로도 호출할 수도 있습니다. 하지만 이때 Object가 새로 생성이 되어 할당이 되기때문에 똑같은 모양을 한 두개의 함수가 되는 것이지요. 아래의 예를 보면 이해가 빠르실겁니다.

>>> def a():
...     print('원래함수')
...
>>> a()
원래함수
>>> b = a
>>> b()
원래함수
>>> def a():
...     print('바뀐함수')
...
>>> a()
바뀐함수
>>> b()
원래함수

다른 언어들에서는 위의 a같은 함수는 함수가 아니라 프로시저라고 할 수도 있겠습니다. 왜냐면 함수는 항상 값을 반환 해야 하는데 위의 함수는 처리만 하고 끝나버리는 함수니까요. 사실 파이썬 에서는 return문을 명시하지 않아도 항상 값을 반환받게 됩니다. 바로 None을 반환하지요. 아래 예제를 보시면 확인이 되실거에요.

>>> def c():
...     pass
...
>>> print(c())
None

None이 반환되는게 싫으시면 함수에서 특정 값을 반환하시면 됩니다.

>>> def c():
...     result = []
...     result.append(1)
...     result.append(2)
...     return result
...
>>> print(c())
[1, 2]

아래는 파이썬에 새로 추가된 특징들입니다:

  • return문은 값을 반환합니다. 그런데 함수에서 아무 것도 return하지 않는다면 None이 반환됩니다.
  • result.append(1)result객체안의 메쏘드를 호출합니다. 메쏘드는 함수는 함수인데 객체 안에 “소속된” 함수를 메쏘드라고 부르고 obj.methodname형식으로 호출하게 됩니다. 여기서 obj는 객체이며, methodname은 하나의 type으로써 객체 안에 선언된 함수입니다.

More on Defining Functions

함수를 정의할때 매개변수에 대한 특징을 미리 설정하는 것이 가능합니다. 3가지 형태가 있는데 복합적으로 섞어서 사용도 가능합니다.

Default Argument Values

가장 흔하게 쓰이는 방법은 바로 매개변수의 기본값을 설정하는 것입니다. 매개변수의 기본값이 설정되어 있는 함수는 정의된 매개변수의 개수보다 더 적은 변수가 인자로 들어왔을때 넘겨 받지 못한 변수에 대해서는 미리 설정해둔 기본값을 사용합니다.

def ask_ok(prompt, retries=4, reminder='Please try again!'):
    while True:
        reply = input(prompt)
        if reply in {'y', 'ye', 'yes'}:
            return True
        if reply in {'n', 'no', 'nop', 'nope'}:
            return False
        retries = retries - 1
        if retries < 0:
            raise ValueError('invalid user response')
        print(reminder)

이 함수는 다양한 형태로 호출이 될 수 있는데

  • 첫째는, 반드시 넘겨주어야하는 기본값이 없는 인자만 가지고 호출했을 때 입니다. 이때는 나머지 두개의 매개변수는 미리 설정된 기본값을 가지게 됩니다: ask_ok('Do you really want to quit?')
  • 두번째는, 필수 매개변수와 함께 두번째 인자를 가지고 호출했을때 입니다. 이때는 두번째 인자가 기본값을 대체하여 넘겨받은 값으로 결과를 도출하고, 세번째 인자는 여전히 기본값을 가집니다: ask_ok('OK to overwrite the file?', 2)
  • 마지막으로, 매개변수 3개를 다 넘겨주었을때 입니다. 이때는 3개의 매개변수가 넘겨받은 값으로 설정되어 결과를 도출합니다: ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')

위의 예제에서 in이라는 연산자를 사용했는데요, 이것은 어떤 배열이나 리스트안에 원하는 값이 있는지 확인하기 위한 비교연산자입니다.

함수의 매개변수의 기본값은 변수로도 선언하여 좀더 동적인 함수를 만들수가 있는데요. 이때 주의 하셔야하실 점은 해당 변수의 값이 함수가 정의되는 시점에 어떤 값을 가지느냐에 따라서 매개변수의 기본값이 정해집니다. 나중에 해당 변수의 값을 바꿔도 이미 함수가 정의된 시점 이후에 값을 바꾸면 함수 매개변수의 기본값에는 영향을 미치지 않습니다.

>>> i = 5
>>>
>>> def f(arg=i):
...     print(arg)
...
>>> i = 6
>>> f()
5

⛔️ 매우 중요한 경고 ⛔️
기본값은 오직 한번만 설정 될 수 있지만, 만약 기본값이 리스트나 딕셔너리처럼 변동이 가능한 객체라면 이야기가 달라집니다. 기본값에는 변수의 주소만 저장이 되기 때문에 listdict의 경우에 항목이 추가되면 기본값도 달라질 수 있습니다.

>>> def f(a, L=[]):
...     L.append(a)
...     return L
...
>>> print(f(1))
[1]
>>> print(f(2))
[1, 2]
>>> print(f(3))
[1, 2, 3]

만약에 기본값이 자꾸 바뀌는 상황을 만들고 싶지 않다면 함수 호출시 값이 안들어온 경우를 함수 내에서 if로 잡아내서 기본값을 정해줄 수도 있습니다.

>>> def f(a, L=None):
...     if L is None:
...         L = []
...     L.append(a)
...     return L
...
>>> print(f(1))
[1]
>>> print(f(2))
[2]
>>> print(f(3))
[3]

Keyword Arguments

함수는 매개변수를 갖고 호출할때 값과 함께 변수명을 함께 넘겨주어 key=value형태로 호출 할 수 있습니다. 아래 예제를 함께 보시죠.

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):
    print("-- This parrot wouldn't", action, end=' ')
    print("if you put", voltage, "volts through it.")
    print("-- Lovely plumage, the", type)
    print("-- It's", state, "!")

위의 함수는 voltage라는 필수 매개변수를 하나 가지고, state, action, 그리고 type 이렇게 3개의 선택적인 매개변수를 가집니다. 이 함수는 아래와 같이 다양한 형태로 호출 할 수 있습니다.

parrot(1000)                                          # 1개의 위치 매개변수
parrot(voltage=1000)                                  # 1개의 키워드 매개변수
parrot(voltage=1000000, action='VOOOOOM')             # 2개의 키워드 매개변수
parrot(action='VOOOOOM', voltage=1000000)             # 2개의 키워드 매개변수
parrot('a million', 'bereft of life', 'jump')         # 3개의 위치 매개변수
parrot('a thousand', state='pushing up the daisies')  # 1개의 위치, 1개의 키워드

voltage변수가 필수 매개변수이긴 하지만 key=value형태로 호출 한다면 뒷쪽에 있어도 상관이 없습니다. 물론 key가 없이 호출이 된다면 반드시 첫번째 인자로 넘겨주어야 하겠지만요. 아래는 이 함수를 호출할 시 에러가 나는 경우들 입니다.

parrot()                     # 필수 매개변수 없음
parrot(voltage=5.0, 'dead')  # key=value로 호출을 시작하면 그 뒤로는 전부 key=value여야함
parrot(110, voltage=220)     # 첫번째 위치가 이미 voltage인데 두번째 또 voltage를 넘김
parrot(actor='John Cleese')  # actor라는 매개변수는 함수선언시 매개변수로 등록되지 않았음

주석에서 설명했듯이 필수 매개변수를 빼먹어서는 안되고, 앞쪽의 인자가 key=value형태로 호출한다면 그 뒤로부터는 반드시 key=value의 형식을 가져야합니다. 그리고 같은 인자가 또 들어와서는 안됩니다.

>>> def function(a):
...     pass
...
>>> function(0, a=0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: function() got multiple values for argument 'a'

함수 호출시 같은 인자를 중복해서 넘겨주면 TypeError가 나면서 같은 매개변수가 여러번 들어왔다는 에러 메세지가 뜹니다.

함수 설정시 매개변수 선언 부분 맨 마지막에 **name이라는 형식으로 마지막 인자가 선언이 되면, 이건 dict형태로 key=value값을 가지는 여러개의 변수를 받겠다는 뜻입니다. 또한 *name도 설정이 가능한데 이건 key없이 tuple로 여러개의 값을 넘기겠다는 의미입니다. 그리고 이 두개는 섞어서 쓸수도 있습니다.

def cheeseshop(kind, *arguments, **keywords):
    print("-- Do you have any", kind, "?")
    print("-- I'm sorry, we're all out of", kind)
    for arg in arguments:
        print(arg)
    print("-" * 40)
    for kw in keywords:
        print(kw, ":", keywords[kw])

위의 함수를 호출하는 모습은 다음과 같습니다.

cheeseshop("Limburger", "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper="Michael Palin",
           client="John Cleese",
           sketch="Cheese Shop Sketch")

그리고 이것은 아래의 결과를 출력합니다.

-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch

다중 값을 가지는 매개변수는 함수호출 시 나열한 순서와 동일하게 변수에 저장이 됩니다.

Special parameters

기본적으로 매개변수는 넘겨받는 위치라던가 아니면 key를 명시해서 넘겨주는 방법이 있습니다. 읽기 좋고 성능이 좋은 코드를 위해서 매개변수를 받는 방법을 제한적으로 하도록 하는 것이 좋습니다. 그래서 개발자가 함수가 선언된 것을 읽을때 position에 의해서만 매개변수를 넘겨받는 함수인지,positionkeyword를 함께 받는 함수인지, keyword만 받는 함수인지를 바로 알수 있게 말입니다.

함수 선언은 다음과 같아야 합니다:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):
      -----------    ----------     ----------
        |             |                  |
        |        Positional or keyword   |
        |                                - Keyword only
         -- Positional only

/*는 선택사항입니다. 만약 사용된다면 이 기호들은 어떻게 매개변수를 넘겨받을지 그 형식을 지정합니다. /앞에 있는 매개변수는 position으로만 넘겨줄수 있고, 그 뒤에 오는 매개변수는 positionkeyword를 둘다 허용하고, *뒤의 매개변수들은 오직 keyword로만 함수에 넘겨집니다.

Positional-or-Keyword Arguments

만약 함수선언시 매개변수에 /*가 보이지 않는다면 그건 바로 position을 기준으로 매개변수를 넘기거나 keyword로 넘기겠다는 걸 의미합니다.

Positional-Only Parameters

만약 함수선언시 매개변수가 /앞에 선언되어 있다면 그 매개변수들은 오직 position으로만 호출할 수 있는 매개변수들 입니다. 걔네들은 key=value형태로 호출될 시 에러가 납니다. 만약 /가 없다면 그 함수에는 position으로만 접근할 수 있는 매개변수는 없다고 할 수 있겠습니다.

참고로, /뒤에 따라오는 매개변수들은 position으로도 넘겨줄수 있고, keyword형식으로도 넘겨줄수 있으며, *의 존재 여부에 따라 keyword만 허용 할 수도 있습니다.

Keyword-Only Arguments

만약 함수의 매개변수를 key=value형식으로만 받고 싶다면 *를 넣으면 됩니다. *를 첫번째 매개변수 앞에 넣으면 그 함수는 모든 매개변수를 key=value형식으로만 받을 수 있습니다.

Function Examples

다음은 /*를 사용한 함수 선언의 예들입니다.

>>> def standard_arg(arg):
...     print(arg)
...
>>> def pos_only_arg(arg, /):
...     print(arg)
...
>>> def kwd_only_arg(*, arg):
...     print(arg)
...
>>> def combined_example(pos_only, /, standard, *, kwd_only):
...     print(pos_only, standard, kwd_only)
...

첫번째 함수, standard_arg는 가장 익숙한 형태죠? 아무런 제약이 없기 때문에 position에 맞춰서 value만 보내도 문제가 없고, key=value의 형태로 호출해도 문제가 없습니다.

>>> standard_arg(2)
2
>>> standard_arg(arg=2)
2

두번째 함수, pos_only_arg/가 보이죠? /앞의 모든 매개변수들은 오직 선언된 순서로만 넘겨줄수 있어 position에 맞춰 value만 넣어 호출합니다. key=value로 호출을 시도하면 에러가 납니다.

>>> pos_only_arg(1)
1
>>> pos_only_arg(arg=1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pos_only_arg() got some positional-only arguments passed as keyword arguments: 'arg'

세번째 함수, kwd_only_args는 가장 처음에 *가 있어서 그 뒤로 오는 모든 매개변수는 key=value형태로만 호출이 가능하기 때문에 이 경우에는 모든 매개변수들을 keyword와 함께 호출해야합니다. value만 넣고 호출한 경우에는 에러가 납니다.

>>> kwd_only_arg(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given
>>> kwd_only_arg(arg=3)
3

마지막으로 /*를 둘다 넣어서 함수를 선언한 경우인데요, 이때는 3가지 특징이 복합적으로 작용하게 됩니다. 아래 호출한 예들을 보시면 더욱 이해가 쉬우실 거에요.

>>> combined_example(1, 2, 3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: combined_example() takes 2 positional arguments but 3 were given
>>> combined_example(1, 2, kwd_only=3)
1 2 3
>>> combined_example(1, standard=2, kwd_only=3)
1 2 3
>>> combined_example(pos_only=1, standard=2, kwd_only=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: combined_example() got some positional-only arguments passed as keyword arguments: 'pos_only'

마지막으로 한가지더! 바로 **kwds를 사용할 때 주의하실 점이 있는데요. 설명드린대로 **가 들어가면 key=value형태의 배열을 dict으로 넘겨받게 되어 매개변수의 이름을 지정할 수 없게됩니다. 만약 이때 **kwds이전에 선언된 매개변수의 이름이 **kwds에도 똑같은 이름으로 들어오게 되면 아무래도 함수안에서 혼선이 있을 수 있겠지요.

def foo(name, **kwds):
    return 'name' in kwds

위의 함수는 만약 kwdsname이라는 변수가 있는지 확인하고 있으면 True를 반환하는 함수 입니다. 하지만 이 함수가 True를 반환할 일은 절대 없습니다. 왜냐면 name이라는 이름의 매개변수가 이미 존재하는 경우에 kwds에 같은 key를 넣어 함수를 호출하면 에러가 나기 때문입니다.

>>> foo(1, **{'name': 2})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'foo' is not defined

하지만 예외적으로 /를 사용한 경우에는 이게 가능합니다. name/앞에 정의가 되어 있고, 그 이후에 **kwds가 정의되었다면 그때는 namekwds안에 key값으로 들어갈 수 있습니다.

>>> def foo(name, /, **kwds):
...     return 'name' in kwds
...
>>> foo(1, **{'name': 2})
True

다르게 해석하면, position으로만 호출이 되는 매개변수 name/**를 복합적으로 사용해서 key=value로도 호출을 할 수 있습니다.

Recap

아래의 경우들은 어떤 경우에 어떤 특징의 매개변수를 사용해야할지를 결정하는데 도움이 될겁니다.

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):

가이드라인:

  • position으로 매개변수를 구분하여 value만 보내는 경우: 사용자에게 함수의 매개변수 이름을 노출하고 싶지 않은 경우. 그리고 매개변수의 이름이 아무런 의미가 없는 경우에도 유용합니다. 아니면, 함수가 호출될때 매개변수의 순서가 중요한 경우에도 /를 쓸수 있구요, 마지막으로 positional 매개변수와 키워드 인수(**kwds)를 취하고 싶은 경우에 필요합니다.
  • key=value만 허용하는 경우: 매개변수의 이름이 큰 의미를 가질때 주로 사용하고, 그것으로 인해 함수를 사용하는데 있어서 훌륭한 설명으로 역할을 할때, 또는 변수명을 명시함으로 인해 순서만으로 이루어지는 경우 범할 수 있는 실수를 미연에 방지하고자 할때 사용됩니다.
  • 함수를 API로 제공할때는 반드시 position-only로 매개변수명을 만드시기 바랍니다. 나중에 매개변수의 이름을 변경해야만 하는 상황이 되었을때 이미 공개된 API를 사용자들에게 변수명을 바꾸라고 다시 공지할 수 없으니까요.

Arbitrary Argument Lists

이번에는 파이썬에서 자주 사용되지 않는 옵션이지만 함수에서 전달할 값들을 나열한 객체를 매개변수로 넣고 전달하는 arbitrary number of arguments에 대해서 이야기 해보도록 하겠습니다. 이 매개변수들은 Tuples로 구성되어있습니다(더보기 Tuples and Sequences). 보통 이 옵션을 사용하기 전에 일반 매개변수를 몇개 먼저 나열해도 되고 아니면 아무것도 안넣고 바로 *args를 넣으셔도 됩니다.

def write_multiple_items(file, separator, *args):
    file.write(separator.join(args))

보통 이 variadic arguments는 매개변수 목록의 마지막에 옵니다. 왜냐면 이 특별한 매개변수는 함수에 전달된 다른 매개변수들을 다 잡아먹어버리거든요. 만약 다른 일반 매개변수가 *args 이 후에 와야하면 반드시 key=value형태로만 받으세요.

>>> def concat(*args, sep="/"):
...     return sep.join(args)
...
>>> concat("earth", "mars", "venus")
'earth/mars/venus'
>>> concat("earth", "mars", "venus", sep=".")
'earth.mars.venus'

Unpacking Argument Lists

매개변수가 이미 list나 tuple에 들어가 있을때 함수를 호출하여 unpacking해야하면 반대의 상황이 연출됩니다. 예를 들어, 빌트인 함수 range()가 있습니다. 이 함수는 start와 stop 이 두개의 매개변수를 기다리고 있습니다. 만약 그 변수들을 따로따로 넣는것이 어려운 상황이라면, 매개변수를 tuple이나 list에 담아 *로 넘겨보세요. 동일한 결과를 기대할 수 있습니다.

>>> list(range(3, 6))
[3, 4, 5]
>>> args = [3, 6]
>>> list(range(*args))
[3, 4, 5]

이와 같은 맥락에서, dict도 여러개로 정의된 key=value 매개변수를 **연산자를 이용해서 한번에 전달 할 수 있습니다.

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print("-- This parrot wouldn't", action, end=' ')
...     print("if you put", voltage, "volts through it.", end=' ')
...     print("E's", state, "!")
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

위의 함수에서 보듯이 여러개의 변수로 함수의 인자를 선언했지만 3개의 변수를 dict에 묶어서 한번에 전달하는 것이 가능합니다.

Lambda Expressions

lambda라는 키워드를 사용해서 간단하게 혹은 임시로 쓸 함수를 생성할 수 있습니다. 다음의 매우 간단한 공식은 사실 함수이며, 두개의 매개변수를 받아 그 합을 반환합니다: lambda a, b: a+b. 람다함수는 함수가 요구되는 어떤 상황에서도 사용될 수 있습니다. 람다는 문법적으로 매우 까다로운데 특히 모든 람다함수는 “한줄로” 정의가 되야합니다.

사실 람다함수는 일반 함수를 좀더 용이하게 선언하게 해주는 사탕과도 같은 기능입니다. 중첩 함수 정의와 마찬가지로 람다 함수는 포함 범위에서 변수를 참조할 수 있습니다.

>>> def make_incrementor(n):
...     return lambda x: x + n
...
>>> f = make_incrementor(42)
>>> f(0)
42
>>> f(1)
43

위의 예제를 보시면 make_incrementor라는 함수는 그 안에서 람다로 정의된 또 다른 함수를 반환합니다. 해당 함수를 호출할때 넘겨받은 매개변수 42를 람다함수에서는 고정된 값으로 사용합니다.

>>> pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
>>> pairs.sort(key=lambda pair: pair[1])
>>> pairs
[(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

위의 예제는 pairs라는 tuple로 구성된 list를 정렬하는 코드입니다. list.sort()를 호출할때 매개변수로 key를 함께 호출할 수 있는데, 이때 이 key라는 매개변수에 함수를 lambda로 바로 선언해서 즉석에서 넘겨주죠. 이 sortkey는 특별히 리스트의 아이템들이 하나의 변수로 구성된게 아니라 여러개의 값으로 이루어져 있을때, 해당 아이템의 변수중에 어떤 것을 기준으로 정렬을 해야할지에 대해서 람다로 설명하여 sort에게 알려주는 겁니다. key에 정의되는 함수는 해당 리스트의 아이템을 매개변수로 받고, 그중 하나를 선택하는 로직을 람다에 구현하여 결정한 값을 반환하면 sortkey를 돌려 반환받은 값으로 정렬을 진행합니다.

Documentation Strings

이 챕터에서는 코드를 설명하는 doc-string의 내용과 형식에 대해서 이야기 해보도록 하겠습니다.

첫번째 줄은 항상 짧고, 객체의 목적을 취합하여 간명하게 표현해야합니다. 코드에 대한 설명은 함수명이나 타입에서 주저리 주저리 설명해서는 안됩니다(함수명은 동사로 시작하는 것은 제외). 코드는 언제나 간략해야하며 추가 설명은 doc-string에 명확하게 그리고 충분히 설명합니다.

만약 doc-string에 여러줄의 설명이 들어가야 하는 경우 첫번째 줄에 간략한 설명을 넣고, 두번째 줄은 비워 두며, 세번째 줄부터 다른 설명을 시작합니다. 그렇게 간략한 설명과 나머지 자세한 설명간의 구분을 확실히 해둠으로써 필요에 따라 doc-string을 활용할 수 있게 합니다.

파이썬 파서는 문자열이 여러줄에 걸쳐 있을때 들여쓰기가 제대로 안되어 있어도 문자열이기 때문에 들여쓰기를 고쳐주지 않습니다. 문자열안의 들여쓰기를 자동으로 맞춰주는 편집툴을 사용하거나 해서 임의로 들여쓰기를 맞추셔야합니다. 들여쓰기의 로직은 다음과 같습니다. 문자열 안의 첫번째 줄 다음 줄이 비어있지 않다면, 그 줄의 들여쓰기가 전체 문서의 들여쓰기 양의 기준이 됩니다(들여쓰기를 몇으로 할지를 첫번째 줄에서 알아내기란 쉽지 않습니다. 보통 문자열이 시작할때는 따옴표 바로 옆에서 시작하므로 들여쓰기 자체를 안하는 경우가 많으니까요). 이 들여쓰기 기준과 동일한 양의 공백은 모든 줄의 시작부분에서 삭제됩니다. 라인중에 들여쓰기가 기준한 양보다 적은 경우에는 삭제하지 않지만, 그 외의 모든 공백은 제거됩니다. 공백의 들여쓰기는 탭을 확장한 후 테스트가 되야합니다(보통 공백8개까지 확장합니다).
이에 대한 정확한 설명은 여기에서..

아래는 다중 docstring의 예제입니다.

>>> def my_function():
...     """Do nothing, but document it.
...
...     No, really, it doesn't do anything.
...     """
...     pass
...
>>> print(my_function.__doc__)
Do nothing, but document it.

    No, really, it doesn't do anything.

Function Annotations

함수 주석(Function Annotations)은 메타데이타 정보이며, 필수사항은 아닙니다. 이는 함수가 어떤 타입으로 작성이 되었는지를 자세히 기술합니다. (더 자세한 정보는 PEP 3107와 PEP 484를 참고 해 주세요).

주석은 __annotations__에 함수의 내부정보로써 dict형태로 존재하고, 주석이기때문에 실제 함수의 기능과는 관련이 없습니다. 매개변수 주석은 매개변수 이름 뒤에 콜론(:)을 찍고, 그 뒤에 해당 변수가 어떤 데이타 타입을 가지는지 적어줍니다. Return할 데이타에 대한 설명은, 매개변수 목록과 def문의 끝을 나타내는 콜론(:) 사이에 문자열 ->를 찍고그 뒤에 반환할 결과의 데이타 타입을 기술합니다. 아래 예제는 필수 매개변수, 선택적 매개변수 그리고 반환할 결과물의 데이타 타입에 대한 주석을 표현한 것입니다.

>>> def f(ham: str, eggs: str = 'eggs') -> str:
...     print("Annotations:", f.__annotations__)
...     print("Arguments:", ham, eggs)
...     return ham + ' and ' + eggs
...
>>> f('spam')
Annotations: {'ham': <class 'str'>, 'eggs': <class 'str'>, 'return': <class 'str'>}
Arguments: spam eggs
'spam and eggs'

Intermezzo: Coding Style

이제부터 여러분은 좀더 길고 복잡한 파이썬 코드를 작성하게 될거기 때문에 지금이 코딩스타일에 대해서 이야기하기 딱 좋은 타이밍이라고 생각합니다. 대부분의 언어들은 여러 다른 스타일로 좀더 간결하고 형식적으로 쓰여질 수 있습니다. 그래서 어떤 언어들은 다른 언어들 보다 좀더 읽기 편하기도 합니다. 다른 사람들에 의해 읽기 편한 코드를 작성하는 것은 정말 너무 훌륭한 일입니다. 그리고 깔끔하다고 생각되는 코딩스타일을 배워서 본인의 코드에 적용하는 습관도 엄청나게 훌륭하고요.

파이썬에서는 대부분의 프로젝트에서 도입한 코딩스타일 가이드로 PEP 8가 있습니다. 여기서 소개하는 스타일대로 코딩을 하면 읽기에도 좋고 눈이 편안한 코딩이 될것입니다. 모든 파이썬 개발자는 반드시 읽기를 추천드리며, 제가 여지 그중 몇가지 포인트를 추출해서 정리해보았습니다.

  • 들여쓰기는 공백 4개를 이용하시고 탭은 사용하지 마세요. 공백 4개보다 작으면 들여쓰기가 반복되는 경우 유용하고, 그보다 크면 읽기가 편하지만 공백4개가 가장 적당한 크기 입니다. 탭을 사용하는 것은 혼동만 가져다 줄 뿐이기때문에 그냥 사용하지 마세요.
  • 한줄에 문자가 79개 이상된다면 다음 줄로 나누어 코딩하세요. 어떤 개발자는 화면이 좁은 컴퓨터를 가지고 있을 수 있고, 때로 여러개의 코드를 양옆에 놔두고 같이 봐가면서 코딩을 해야하는 경우도 허다하기 때문에 너무 길게 코딩을 하는 것은 바람직하지 않습니다.
  • 함수나 클래스 또는 큰 블락의 코드를 구분해서 보여주기 위해 그 사이에 빈줄을 넣어주세요.
  • 주석은 가급적 코드와 같은 줄에 넣으시기 바랍니다.
  • 함수나 클래스 선언할때 docstring을 꼭 넣으세요
  • 연산자나 콤마, 괄호등을 사용할 때는 보기 편하게 공백을 넣어주세요: a = f(1, 2) + g(3, 4).
  • 클래스나 함수이름을 일관되게 지어주세요; 클래스는 UpperCamelCase 이런 식으로 (camel스타일이라고 하죠), 그리고 함수나 메소드는 lowercase_with_underscores 이런식으로 (이건 snake스타일입니다) . 클래스안에서 내부함수를 정의할때는 메소드의 첫번째 매개변수로 self를 항상 넣어 주세요(클래스와 메소드에 대한 더 자세한 내용은 A First Look at Classes을 참고해주세요).
  • 코드파일을 이상한 엔코딩으로 설정하지 마세요. 전세계적으로 통용되는 캐릭터셋은 UTF-8입니다. 여러분의 코드는 국제적으로 사용이 되어질거니까 특정 국가나 언어에 국한되는 엔코딩은 지양해 주세요. 파이썬은 기본값으로 UTF-8을 채택하였으면 ASCII도 때에따라 사용하기 좋은 엔코딩입니다.
  • 구분자로 선택하는 값은 ASCII표에 있는 문자로만 사용하세요. ASCII에서 지원하지 않는 문자를 코드파일에 넣으면 다른 언어를 사용하는 개발자 환경에서는 깨져서 보일수도 있습니다.

References