Python Official Site의 Tutorial 에 대한 내용을 공부하면서 정리한 글.


기본적으로 이 글은 Tutorial의 각 챕터에 대한 간략한 설명과

노란색 박스 안에 있는 코드를 보는 것 만으로는 이해하기 어려운 부분이나,

매번 기억해 두어야 할 내용들 그리고 C/C++ 과는 좀 다른 부분

혹은 Python 2.x 버전과는 다른 부분 위주로 정리해 보려 함.

글의 순서는 원래 문서의 챕터에 따름.


이 글의 범위:

4. More Control Flow Tools




4. More Control Flow Tools

바로 이전 글에 보여준 while문 외에, 다른 control flow 문들에 대한 설명.


4.1. if Statements

기본적인 사용방법 예제. elif 부분이나 else 부분은 없어도 된다.

python에는 switch-case문은 없지만 if .. elif ... elif ... 문으로

switch-case문을 대체할 수 있다.

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


4.2. for Statements

python의 for 문은 C 나 Pascal과는 조금 다르다.

항상 iterable 을 사용하여 반복을 한다.

기본적인 사용법은 아래와 같다.

>>> # Measure some strings:

... words = ['cat', 'window', 'defenestrate']

>>> for w in words:

...     print(w, len(w))

...

cat 3

window 6

defenestrate 12

만약, for 루프 내에서 for 문의 iterating에 사용되는 데이터를 수정해야 한다면,

iteration에 사용되는 데이터는 아래와 같이 복사본을 사용해야 할 것이다.

>>> for w in words[:]:  # Loop over a slice copy of the entire list.

...     if len(w) > 6:

...         words.insert(0, w)

...

>>> words

['defenestrate', 'cat', 'window', 'defenestrate']


4.3. The range() Function

일정한 순서의 숫자들을 반복(iterate)해야 한다면,

range()라는 내장(built-in) 함수를 사용하면 된다.

다음의 사용예를 보자.

>>> for i in range(5):

...     print(i)

...

0

1

2

3

4


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


>>> print(range(10))

range(0, 10)


>>> list(range(5))

[0, 1, 2, 3, 4]

첫번째 예제를 보면 range(10)으로 리턴되는 object가 list처럼 사용되지만,

실제로는 그렇지 않다. 예제의 마지막 부분을 보면 단순히 range(10)을 한다고 하여

list가 리턴되지 않는다. 하지만 range(10)에 리턴되는 object는 iterable 하기 때문에,

for 문에서도 사용할 수 있었던 것이다.

그리고 list() 함수를 통해 list로 만들 수 있다.


4.4. break and continue Statements, and else Clauses on Loops

break 와 continue 문의 사용법은 C 와 동일하게 사용된다.

루프문도 else 절을 가질 수 있다. 이 else 절은 break 가 아닌

정상적인 경우로 for 나 while 루프가 종료된 경우,

else 절이 수행된다.

(for 문은 list 를 모두 소진하여 루프가 종료된 경우,

 while 문은 조건이 false 가 되어 루프가 종료된 경우가 되겠다)

아래의 예제를 보자.

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

python에서는 들여쓰기(identation)가 매우 중요하다.

위의 예제의 경우도 else 의 위치가 바로 이전의 if 문 보다 왼쪽에 위치해 있기 때문에,

if 에 대한 else 가 아니라 for 루프에 대한 else 로 해석된다.


4.5. pass Statements

pass 문은 아무것도 하지 않는다.

문법적으로 statement가 필요하지만, 아무것도 하지 않으려 할 때 사용된다.

예를 들면 빈 클래스나 아무일도 하지 않는 함수를 만들 때 사용할 수 있겠다.

>>> class MyEmptyClass:

...     pass

...


>>> def initlog(*args):

...     pass   # Remember to implement this!

...


4.6. 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' 키워드로 시작하여 함수이름과 괄호로 묶인 파라메터 리스트가 나온다.

함수의 내용은 다음 줄 부터 시작되며 반드시 들여쓰기(ident)가 되어야 한다.

위 예제의 함수 본문의 첫 줄은 선택사항으로 함수에 대한 설명을 적는다.

이 문자열을 funtion's documentation string 혹은 docstring 이라 한다.

docstring을 잘 작성해 둔다면, API 문서 등을 생성하는 데 도움이 된다.

함수 내에서 사용되는 변수는 local symbol table에 저장되고,

함수를 벗어나게 되면 더 이상 사용할 수 없다.

global variable 을 사용하려 할 때는 C 처럼 바로 접근할 수 있는 것이 아니라,

'global' 키워드를 사용해야 한다.

>>> a=10

>>> def f():

a=20


>>> print (a)

10

>>> f()

>>> print (a)

10


>>> def f():

    global a

a=20


>>> print (a)

10

>>> f()

>>> print (a)

20

함수의 파라메터는 호출되는 함수의 local symbol table에 저장되기 때문에,

arguments는 call by value를 사용하여 전달된다고 할 수 있겠다.

단, 이 value는 항상 object에 대한 reference이다.

C++ 로 치면 아래의 예제에서 함수 원형은 void f(&l); 정도 되겠다.

아래의 예제를 보면 list object의 복사본이 함수로 전달되는 것이 아니고,

실제 list object에 대한 reference가 넘어가기 때문에,

함수내에서 list의 내용을 변경하게 되면,

함수 호출 전/후로 list의 내용이 바뀌게 된다.

(각주: 그렇게 때문에 call by object reference 라고 하는게  더 정확한 설명이 될 것이다)

>>> a=[10,20,30]

>>> def f(l):

l[0]=50


>>> print(a)

[10, 20, 30]

>>> f(a)

>>> print(a)

[50, 20, 30]

함수도 다른 변수에 할당하여 다른 이름으로 사용할 수 있다.

마치 C 의 함수포인터 같은데... 아래 예제를 보자.

>>> fib

<function fib at 10042ed0>

>>> f = fib

>>> f(100)

0 1 1 2 3 5 8 13 21 34 55 89

함수는 return 문을 통해 값을 리턴할 수 있다.

return 문이 없는 함수의 리턴값은 None이다.(None은 built-in name이다.)

>>> def fib2(n): # return Fibonacci series up to n

...     """Return a list containing the Fibonacci series up to n."""

...     result = []

...     a, b = 0, 1

...     while a < n:

...         result.append(a)    # see below

...         a, b = b, a+b

...     return result

...

>>> f100 = fib2(100)    # call it

>>> f100                # write the result

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]


>>> def f():

pass


>>> print (f())

None

result.append(a) 는 result = result + [a] 와 동일하지만 더 효율적이다.


4.7. More on Defining Functions

함수의 arguments는 3가지 형태가 있으며, 섞어서 사용을 할 수가 있다.


4.7.1. Default Argument Values

arguments에 default value를 지정해 두어,

함수 호출 시 default value가 지정된 argument가 생략되면

default value를 사용하도록 한다. 다음의 예제를 보자.

def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):

    while True:

        ok = input(prompt)

        if ok in ('y', 'ye', 'yes'):

            return True

        if ok in ('n', 'no', 'nop', 'nope'):

            return False

        retries = retries - 1

        if retries < 0:

            raise IOError('refusenik user')

        print(complaint)

위와 같이 정의된 함수라면 아래와 같이 호출 할 수 있다.

(위의 예제에서 if ~ in 의 사용법도 봐 두자.)

ask_ok('Do you really want to quit?')

ask_ok('OK to overwrite the file?', 2)

ask_ok('OK to overwrite the file?', 2, 'Come on, only yes or no!')

default value는 변수로 지정할 수도 있다.

함수가 정의되는 위치에서 evaluate되는 값을 사용한다.

예를 들어 아래 예제의 경우 '5'가 출력될 것이다.

i = 5


def f(arg=i):

    print(arg)


i = 6

f()

경고: default value는 단 한번만 evaluate된다. 

이것은 default value가 list나 dictionary 같은 mutable object인 경우,

다음과 같이 의도하지 않은 결과를 보여줄 수도 있다.

def f(a, L=[]):

    L.append(a)

    return L


print(f(1))

print(f(2))

print(f(3))

위의 예제는 아래와 같은 결과를 출력한다.

[1]

[1, 2]

[1, 2, 3]

만약 매번 f() 함수를 호출 할 때마다, L 이 초기화 되길 원한다면,

아래와 같이 사용해야 할 것이다.

def f(a, L=None):

    if L is None:

        L = []

    L.append(a)

    return L


4.7.2. Keyword Arguments

함수를 호출할 때, keyword arguments를 사용할 수 있다.

아래 예제를 보자.

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, "!")

parrot(1000)                                          # 1 positional argument

parrot(voltage=1000)                                  # 1 keyword argument

parrot(voltage=1000000, action='VOOOOOM')             # 2 keyword arguments

parrot(action='VOOOOOM', voltage=1000000)             # 2 keyword arguments

parrot('a million', 'bereft of life', 'jump')         # 3 positional arguments

parrot('a thousand', state='pushing up the daisies')  # 1 positional, 1 keyword

위와 같이 직접 키워드와 값을 지정하여 함수를 호출 할 수 있다.

또한, 임의의 갯수를 argument로 받거나 dictionary를 argument로 받을 수도 있다.

*arguments - arbitrary argument는 **keywords - dictionary argument 보다

위치가 앞에 와야한다. 아래 예제를 보면 어떻게 사용하는지 알 수 있다.

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)

    keys = sorted(keywords.keys())

    for kw in keys:

        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.

----------------------------------------

client : John Cleese

shopkeeper : Michael Palin

sketch : Cheese Shop Sketch


4.7.3. Arbitrary Argument Lists

함수에서 임의의 갯수의 arguments를 받기위해 사용하는 방법인다.

이 arguments는 tuple 데이터 타입이 될 것이다.

일반적으로 이 arbitrary argument는 일반적인 argument의 가장 뒤에 위치하지만,

위에서 본 dictionary argument나 아래 예제에서 볼 keyword argument는

arbitrary argument 뒤에 위치할 수도 있다.

def write_multiple_items(file, separator, *args):

    file.write(separator.join(args))

위는 일반적인 사용 법. 아래는 keyword argument와 함께 사용하는 예제.

>>> def concat(*args, sep="/"):

...    return sep.join(args)

...

>>> concat("earth", "mars", "venus")

'earth/mars/venus'

>>> concat("earth", "mars", "venus", sep=".")

'earth.mars.venus'


4.7.4. Unpacking Argument Lists

list 나 tuple을 unpack 하여 함수인자로 넘길 수 있다.

같은 방식으로 dictionary로 unpack하여 인자로 넘길 수 있다.

아래 예제를 참고하자.

>>> list(range(3, 6))            # normal call with separate arguments

[3, 4, 5]

>>> args = [3, 6]

>>> list(range(*args))            # call with arguments unpacked from a list

[3, 4, 5]


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


4.7.5. Lambda Forms

많은 사람들의 요구에 의해 Lisp과 같은 functional programming language의 몇 가지 특징이

python에도 추가되었다. lambda 함수가 그 중 하나인데,

lambda 키워드로 작은 익명의 함수를 만들 수 있다.

lambda 형식은 function object가 필요한 어떤 곳이듯 사용될 수 있다.

그리고 문법적으로 항상 하나의 expression으로 제한된다.

아래의 예제를 참고하자.

>>> def make_incrementor(n):

...     return lambda x: x + n

...

>>> f = make_incrementor(42)

>>> f(0)

42

>>> f(1)

43


>>> f = lambda a,b:a+b

>>> f(10,20)

30


4.7.6. Documentation Strings

docstring의 내용과 형식에 대한 몇 가지 규칙이 있다.

첫 번째 줄은 object의 목적에 대해 짧고 간결하게 적는다.

짧게 만들기 위해 object의 이름이나 타입을 적지 않는다.

(단, 함수의 이름이 함수의 동작을 설명하는 동사가 되는 경우는 제외한다.)

이 줄은 대문자로 시작하여 마침표로 끝난다.


만약 docstring이 여러 줄이라면, 함수의 요약이 나머지 설명과 시각적으로 분리되도록,

두 번째 줄은 빈 줄이어야 한다.

이 후 줄들은 object의 호출 규칙, side effect 등을 설명하는

하나 이상의 문단으로 이루어진다.


python 파서는 multi-line 문자열에 대해서는 들여쓰기(identation)를 잘라내지 않기 때문에,

필요하다면 들여쓰기를 없애는 작업이 필요할 것이다.

이러한 작업은 다음과 같은 규칙을 사용한다.

첫 번째 줄 이후 처음으로 나타나는 내용이 있는 줄(non-blank line)의 들여쓰기를

전체 docstring의 들여쓰기로 결정한다.


아래는 multi-line 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.


4.7.7. Function Annotations

이것은 완전한 선택사항이다.

python 이나 standard library 둘 다 이것을 사용하지 않는다.

자세한 것은 직접 tutorial을 참고 할 것.


4.8. Intermezzo: Coding Style

함수와는 관계 없으나 이제 더 길고 복잡한 python 코드를 작성하게 될텐데,

지금이 코딩 스타일에 대한 이야기를 하기에 좋은 타이밍이다.

PEP 8(Python Enhancement Proposals 8)는 대부분의 python projects가 준수하는

style guide를 나타낸다. 이것은 매우 가독성 있고 눈이 즐거운 코딩 스타일이다.

모든 python 개발자들은 반드시 읽어야 할 것이다.

여기는 가장 중요한 점만 뽑아놓았다.

- 4-space 들여쓰기를 사용하라. tab은 사용하지 말것.

  4 spaces는 더 적은 들여쓰기와 더 큰 들여쓰기의 적절한 타협점이다.

  tab은 혼란을 야기할 수 있으니 사용하지 않는 것이 좋다.


- 한 줄이 79 문자를 넘지 않도록 줄을 나누라.

  이것은 작은 화면을 가진 유저를 위한 것이고,

  더 큰 화면에서 여러 코드 파일을 동시에 볼 수 있게 해 준다.


- 함수와 클래스 그리고 함수 내부의 논리적 코드 블럭을 나누기 위해

  빈 줄을 사용하라.


- 가능하다면, 주석은 해당 코드와 같은 라인에 두라.


- docstrings를 사용하라.


- 연산자 앞뒤와 콤마 뒤에는 공백을 두라. 하지만 괄호 바로 안쪽은 붙여쓰라.

  a = f(1, 2) + g(3, 4)


- class 이름은 CamelCase 형태로, 함수는 lower_case_with_underscores 형태로 쓰라.

  class methon 의 첫 번째 argument의 이름은 항상 self 를 사용하라.


- 소스 파일의 인코딩은 UTF-8을 사용하라. 여의치 않다면 ASCII 도 잘 동작할 것이다.


- 마찬가지로, 식별자로 non-ASCII 문자를 사용하지 마라.



반응형

설정

트랙백

댓글

Python Official Site의 Tutorial 에 대한 내용을 공부하면서 정리한 글.


기본적으로 이 글은 Tutorial의 각 챕터에 대한 간략한 설명과

노란색 박스 안에 있는 코드를 보는 것 만으로는 이해하기 어려운 부분이나,

매번 기억해 두어야 할 내용들 그리고 C/C++ 과는 좀 다른 부분

혹은 Python 2.x 버전과는 다른 부분 위주로 정리해 보려 함.

글의 순서는 원래 문서의 챕터에 따름.


이 글의 범위

1. Whetting Your Appetite 3. An Informal Introduction to Python



1. Whetting Your Appetite

특별한 내용은 없음. C/C++/Java 나 Shell Script 보다 Python 이 나은 이유를 설명함.


2. Using the Python Interpreter

Python 인터프리터 사용에 대한 내용.


2.1. Invoking the Interpreter

2.1.1. Argument Passing

2.1.2. Interactive Mode

2.2. The Interpreter and Its Environment

2.2.1. Error Handling

2.2.2. Executable Python Scripts

Unix 시스템에서는 Python 스크립트를 바로 실행하기 위한 방법.

아래와 같은 줄을 넣으면 python file.py 형태가 아닌 ./file.py 형태로

바로 Python 스크립트를 실행할 수 있다. 물론 chmod +x 로 실행권한을 줘야한다.

#! /usr/bin/env python3.3

2.2.3. Source Code Encoding

기본적으로 Python 소스파일은 UTF-8로 처리가 되는데, 만약 사용하는 에디터가 UTF-8이 지원이 되지 않는다면,

(요즘은 웬만한 에디터는 다 지원한다. 윈도우의 기본 메모장이라도!)

아래와 같은 라인을 파일의 첫번째나 두번째 라인에 적어 소스파일의 인코딩을 직접 지정해 줄 수 있다.

# -*- coding: cp-949 -*-

지원하는 인코딩의 종류는 여기에서 확인할 수 있다.


2.2.4. The Interactive Startup File

2.2.5. The Customization Modules

3. An Informal Introduction to Python

Python에 대한 간단한 소개. 숫자, 스트링, 리스트에 대한 간단한 예제를 보여준다.


3.1. Using Python as a Calculator

3.1.1. Numbers

+, -, *, /, **, // 와 같은 연산자가 있다.

'/' 연산자의 경우 Python 2.x 과 3.x 가 조금 다르게 동작한다.

아래 예제 참고.

(Python 2.x)

>>> 3/4

0

>>> 3.0/4

0.75


(Python 3.x)

>>> 3/4

0.75

'//' 연산자는 나누셈 후 소숫점 부분을 버린 결과를 보여준다.

'**' 연산자는 제곱 연산

특별히 '_' 문자는 interactive 모드에서만 사용되는 것으로 마지막으로 계산의 결과를 저장한다.

(print 로 출력된 것이 아닌 순수한 계산결과.)


3.1.2. Strings

Python에서 문자열은 single quotes-작은따옴표('...')와 double quotes-큰따옴표("...")로 표현할 수 있고,

둘 다 같은 결과를 가진다. 작은따옴표 안에서 큰따옴표를 표시할 때나 반대의 경우에는 따로 escape 문자 '\'를

적을 필요가 없다. 작은따옴표 안에서 작은따옴표를 표시항 경우나 큰따옴표 안에서 큰따옴표를 표시할 때는 

'\'를 적어주어야 한다. 아래의 예제를 보면 좀 더 명확해진다.

>>> 'spam eggs'  # 작은 따옴표

'spam eggs'

>>> 'doesn\'t'  # 작은따옴표내에서 작은따옴표를 사용할 때 

"doesn't"

>>> "doesn't"  # 아니면 큰따옴표를 사용한다.

"doesn't"

>>> '"Yes," he said.'

'"Yes," he said.'

>>> "\"Yes,\" he said."

'"Yes," he said.'

>>> '"Isn\'t," she said.'

'"Isn\'t," she said.'

>>> print ('"Isn\'t," she said.')

"Isn't" she said.

마지막 바로 전의 예제는 다소 혼란스러운데, interactive 모드에서 문자열이 echo 될 때, 위와 같이 출력된다.

실제 스크립트에서 '"Isn\'t," she said.'라고 실행하더라도 해당 문자열이 표시(echo)되지는 않는다.

결국 print 명령으로 문자열을 출력해 보면 원하는 결과대로 출력이 된다.

따라서 크게 의미를 둘 필요는 없다.

만일, 문자열에서 '\'이 특수문자가 아닌 문자 그대로 해석이 되길 원한다면 아래와 같이 raw string을 사용한다.

>>> print('C:\some\name')  # here \n means newline!

C:\some

ame

>>> print(r'C:\some\name')  # note the r before the quote

C:\some\name

문자열이 여러줄인 경우 triple-quotes:"""...""" 혹은 '''...'''을 사용할 수 있다.

이 경우 한 줄의 끝에는 자동으로 new line 문자가 포함되는데,

'\'을 줄 끝에 붙이면 이것을 방지 할 수 있다. 아래의 예제를 보라.

>>> print("""\

Usage: thingy [OPTIONS]

     -h                        Display this usage message

     -H hostname               Hostname to connect to

""")

Usage: thingy [OPTIONS]

     -h                        Display this usage message

     -H hostname               Hostname to connect to

문자열내의 한 문자 혹은 부분문자열을 나타낼때는 아래와 같은 방법들이 있다.

>>> word = 'Python'


>>> word[0]  # character in position 0

'P'

>>> word[5]  # character in position 5

'n'


>>> word[-1]  # last character

'n'

>>> word[-2]  # second-last character

'o'

>>> word[-6]

'P'


>>> word[0:2]  # characters from position 0 (included) to 2 (excluded)

'Py'

>>> word[2:5]  # characters from position 2 (included) to 5 (excluded)

'tho'


>>> word[:2] + word[2:]

'Python'

>>> word[:4] + word[4:]

'Python'


>>> word[:2]  # character from the beginning to position 2 (excluded)

'Py'

>>> word[4:]  # characters from position 4 (included) to the end

'on'

>>> word[-2:] # characters from the second-last (included) to the end

'on'

Python 문자열은 변경할 수 없다.(immutable). 그러므로 아래와 같은 assigning은 에러가 발생한다.

>>> word[0] = 'J'

  ...

TypeError: 'str' object does not support item assignment

>>> word[2:] = 'py'

  ...

TypeError: 'str' object does not support item assignment


3.1.3. Lists

대괄호안에 콤마로 분리된 리스트로 씌여진다. 리스트는 다른 타입의 아이템을 가질 수 있지만,

일반적으로 같은 타입의 아이템을 가진다.

기본적인 사용법은 아래와 같다.

>>> squares = [1, 2, 4, 9, 16, 25]

>>> squares

[1, 2, 4, 9, 16, 25]


>>> squares[0]  # indexing returns the item

1

>>> squares[-1]

25

>>> squares[-3:]  # slicing returns a new list

[9, 16, 25]


>>> squares[:]

[1, 2, 4, 9, 16, 25]

마지막 명령은 리스트의 새로운 복사본을 생성하는데,

이것은 for 루프에서 iterable에 사용되는 리스트의 내용이 루프내에서 변경되는 경우,

iterable 을 리스트 자체가 아닌 리스트의 복사본으로 사용하려 할 때 편리하다.


3.2. First Steps Towards Programming

간단한 프로그램 예제. 기본적인 while 루프 및 print() 함수 사용법을 알 수 있다.

>>> # Fibonacci series:

... # the sum of two elements defines the next

... a, b = 0, 1

>>> while b < 10:

...     print(b)

...     a, b = b, a+b

...

1

1

2

3

5

8


반응형

설정

트랙백

댓글

이 글은 Python Tutor 메일링 리스트에 있던 글을 번역한 글입니다.
(영어는 약해서 말이죠..;; 틀린 부분 있으면 지적 해 주세요..)
메일이 오고 갔던 때가 2002년 8월 경이군요...

(원본글을 보려면 아래를 클릭)


--------------------------------------------------------------

> 님들 (--;)
> Tkinter 와 wxPython 의 가장 다른점이 뭔가요?

Thinter 는 표준 파이썬 모듈이고, wxPython 은 아닙니다. 그래서 (wxPython은) 써드파티 라이브러리가 필요합니다.

wxPython 은 grid controls 등과 같은 기능이 더 많습니다. Tkinter 를 사용하여 많은 것을 하려 한다면 Python Mega Widgets (pmw) 와 같은 확장기능을 필요로 할 것입니다. 그래서 어쨌든 써드파티 라이브러리를 필요로 하게 될 것십니다.

만약 단순한 GUI 가 필요하다면, Tkinter 는 어플리케이션 작성을 쉽게 만드는 확실한 장점을 가지고 있습니다. 추가로 다른것을 설치할 필요없이, 파이썬과 당신이 작성한 코드만 있으면 됩니다.

Tkinter 는 Tcl 이라 불리는 인터프리트 언어를 위해 만들어진 Tk 라 불리는 GUI 툴킷을 기반으로 하고 있습니다. 그래서 별로 빠르진 않습니다. wxPthon 은 wxWindows 라 불리는 C++ GUI 툴킷을 기반으로 하고 있습니다. 좀 더 빠르죠. 나는 advanced controls 에 대해서 좀 더 많은 다른 점이 있을 꺼라 생각합니다. 왜냐하면 Tkinter 는 Python 으로 작성된 반면 wxPython 은 C++ 로 작성되었기 때문이죠.

또한, "Python and Tkinter Programming" 이라는 책을 시작으로 Tkinter 에 대한 여러 책들이 있습니다. 그리고 Thinter 프로그래머에게 도움이 될만한 Tcl/Tk 에 대한 책들도 많습니다.

wxPython 문서는 적습니다. 이 문서는 wxWindows C++ 문서에 파이썬 버젼의 다른 점을 설명해 놓은 것입니다. 또한 wxWindows 문서는 전체적으로 최신의 상태로 유지되지 않습니다. 그리고 wxWindows / wxPython 은 조금씩 발전하고 변하는 중입니다. 하지만 대부분의 특징을 예로 만든 좋은 데모 프로그램들을 제공합니다.

두 툴킷 모두 많은 유저가 있습니다. Tkinter 는 표준 모듈이기 때문에 "Thinter community" 라는 것이 (따로) 있는 지는 모르겠습니다. 두 툴킷 모두 관련 책자들이 있으며, 인터넷 상에는 자료들과 도움을 줄 수 있는 사람들이 있습니다.

wxPython 과 wxWindows 는 Tcl/Tk 와 Tkinter 보다 훨씬 더 활동적으로 개발되고 있습니다. 그것이 좋은지 나쁜지는 당신의 판단에 달려 있습니다. Tcl/Tk 는 좀 더 성숙된 툴킷입니다.(앞에도 썼듯이, advanced controls 가 좀 부족하지만 말이죠)

wxPython 은 wxWindows 개발자들이 중요하게 여기고 있습니다.([역자] 원문의 concidered 는 오타인듯 합니다.) 반면에 Tcl/Tk 개발자들은 (아직 개발자가 있긴 한가요?) 파이썬 유저들이 행복할 수 있도록 신경을 쓰는지는 잘 모르겠습니다.

나는 Thinter 가 wxPython 보다 조금 더 많은 플랫폼에서 동작한다고 생각합니다. 하지만 wxPthon 은 Windows, Linux 그리고 많은 Unix 상에서 잘 동작합니다. Mac 포트의 현재 상태는 어떤지 잘 모르겠습니다.

마크 햄몬드와 앤디 로빈슨이 쓴 Python Programming on Win32  라는 책에는 두가지 모두를 다루고 있는 GUI 프로그래밍에 대한 챕터가 있습니다. 온라인에서 볼 수 있습니다.
http://www.oreilly.com/catalog/pythonwin32/chapter/ch20.html
여기에서는 두가지 모두에 대한 예제 코드도 볼수 있습니다.

--------------------------------------------------------------

다음글은 조기 마지막 부분의 링크에 대한 글을 써 볼까 합니다.
다는 말고.. 필요한 내용만...;;
반응형

설정

트랙백

댓글

파이썬 튜토리얼을 대충 훓어본 후, 맨 처음 해 본것은
기존에 쉘 스크립트와 루비를 이용해 만든 유틸리티였습니다.

이 유틸중에 URL 주소로 부터 파일을 다운로드 하는 부분이 있는데
이 부분에 대해서 이야기 해볼까 합니다.

먼저, URL 주소로 부터 파일을 다운로드 받는 방법 입니다.
import urllib

URL = URL주소
urllib.urlretrieve(URL, URL.split('/')[-1])

요렇게 쓰면 파일을 다운로드 할 수 있습니다.
하지만 여기에서 문제가 발생했습니다. 어떤 서버내의 존재하지 않는 파일에 대해서
다운로드를 시도 할 때 exception 이 발생하지 않습니다.
구글님께 물어본 결과 저 현상이 당연하다는 글을 볼 수가 있었습니다.
왜냐하면 존재하지 않는 파일에 대해서 다운로드를 하게 되면
해당 파일이 아닌 다른 내용을 수신하게 되며, 네트웍으로 부터 정상적인
응답을 받았으므로 exception 이 아니라는 것입니다.

예를들면 http://www.naver.com/sdfa.jpg 파일을 위 코드를 사용하여 다운로드를 하게 되면
sdfa.jpg 라는 파일이 생성되며, 아무런 exception 이 발생하지 않습니다.
하지만 sdfa.jpg 라는 파일을 텍스트 에디터로 살펴보면 다음과 같습니다.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>404 Not Found</TITLE>
</HEAD><BODY>
<H1>Not Found</H1>
The requested URL /sdfa.jpg was not found on this server.<P>
</BODY></HTML>

자, 그렇다면 어떻게 하면 다운로드 하려는 파일이 없다는 것을 알 수 있을까요?
머.. 여러 방법이 있겠지만, 제가 찾아낸 방법은 다음과 같습니다.
file = urllib.urlopen(URL)
   try:
       if file.headers.get("content-length") == None:
           raise
       else:
           file.close()
           urllib.urlretrieve(URL, URL.split('/')[-1])           
   except:
      (예외처리...)

이상 어제 삽질의 보고서였습니다. (--)(__)
반응형

설정

트랙백

댓글

2.2.3 Source Code Encoding
파이썬 소스 파일에서는 ASCII 와는 다른 인코딩을 사용할 수 있다. 가장 좋은 방법은 소스 파일의 인코딩을 방법을 정의하는 특별한 주석을 추가하는 것이다.

# -*- coding: encoding -*-

이 선언이 되어 있으면, 소스 파일내의 모든 문자는 encoding 타입으로 인코딩된 문자로 다루어질 것이다. 그리고 선택된 인코딩 타입으로 부터 직접적으로 유니코드를 쓸 수 있다. 사용가능한 인코딩 리스트는 이곳을 참고하라.

예를들어, 유로화 심벌을을 포함하는 유니코드 문자를 쓰기위해서, 유로화 심벌의 서수값(ordinal value) 164 인 ISO-8859-15 인코딩을 사용할 수 있다. 다음 스크립트는 8364 (유로화 심벌에 해당하는 유니코드 값) 를 출력한다.

# -*- coding: iso-8859-15 -*-

currency = u"€"
print ord(currency)


3.1.2 Strings
스트링을 표현하기 위해서 ` 나 " 를 사용할 수 있다.
` 내에서 ` 문자를 표시하기 위해서는 \` 사용하고 " 문자를 표시하기 위해서는 그냥 " 쓰면 된다.
반대로 마찬가지.


4.2 for Statements

>>> # Measure some strings:
... a = ['cat', 'window', 'defenestrate']
>>> for x in a:
... print x, len(x)
...
cat 3
window 6
defenestrate 12

반복문 내에서 리스트 a 의 내용을 바꿀 필요가 있을 때는,
위와 같이 쓰면 문제가 생길 수 있다. 이 경우에는 다음과 같은 표현으로
리스트 a 의 copy 를 사용한다.

>>> for x in a[:]: # make a slice copy of the entire list
... if len(x) > 6: a.insert(0, x)
...
>>> a
['defenestrate', 'cat', 'window', 'defenestrate']

4.1.7 Default Argument Values

i = 5

def f(arg=i):
print arg

i = 6
f()

default value 의 값은 defining scope 의 function definition 때 evaluate 된다.
즉 위의 코드의 결과는 5 가 출력된다.

주의! : default value 는 오직 한번 evaluate 된다. 이것이 list, dictionary 혹은 클래스의 객체와 같이 mutable(내용이 변할 수 있는) object 가 default 가 되는 경우 영향을 미친다.
예를들어, 아래의 코드는

def f(a, L=[]):
L.append(a)
return L

print f(1)
print f(2)
print f(3)

다음과 같은 결과를 출력한다.

[1]
[1, 2]
[1, 2, 3]

만약 연속적인 호출에서 default 를 공유하고 싶지 않다면, 함수 정의를 다음과 같이 해야 한다.

def f(a, L=None):
if L is None:
L = []
L.append(a)
return L


반응형

설정

트랙백

댓글

예전부터 스크립트 언어를 하나 배워야지 생각하고 있었습니다.
몇 가지 언어들이 후보로 나왔습니다.
자바스크립트, 비베스크립트, 펄, 파이썬, 루비 등...
이중에서 플랫폼에 종속적이지 않고 오픈소스이며 비교적 최근에 나온것을
고르다 보니 파이썬과 루비, 이 두가지 언어로 압축 되었습니다.

각각 이런저런 장단점이 있었던거 같습니다.
하지만 일반적으로 사용하기에 크게 문제되는게 아닐듯 하여
제가 선택한 기준은...

Win32 포트의 설치 프로그램의 용량...입니다.

python-2.5.msi  -  10.2 MB
ruby185-21.exe  -  26.3 MB

로.. 파이썬의 압승...
(사실은 파이썬이 좀 더 자료가 많다는 것도 영향을 미쳤죠)

이번에야 말로 좀 더 깊이 있게 공부해 볼까 합니다.



반응형

설정

트랙백

댓글

  • BlogIcon 감성코드 2009.04.06 10:31 답글 | 수정/삭제 | ADDR

    결과는?

    • BlogIcon 아자 2009.04.08 20:44 신고 수정/삭제

      전혀 진전이 없달까...
      당췌 배워도 쓸일이 없다...
      회사에서 컴파일에 쓰는 스크립트는
      죄다 펄이고..

      다시 한번 연구를 해볼까나..
      할만한게 있는지..

  • BlogIcon 14 ROUND 2009.04.08 23:07 신고 답글 | 수정/삭제 | ADDR

    일부러 쓰려고 노력하지 않으면 딱히 회사에서 쓸 일이 없긴 하더라만.
    내 블로그와 구글 닭스에서는 잘 쓰고 있다. -_-;