2014년 7월 8일 화요일

python 문법 중 특이점 대충 정리

python으로 된 코드를 봐야할 상황이 생겨
점프 투 파이썬(https://wikidocs.net/book/1)와
python documentation(https://docs.python.org/3.4/tutorial/index.html)을 보며
특이한 점만 대충 정리함.

문법이 스크립트언어 치곤 기존 c, c++과 유사하고 군더더기 없이 간결함.


[Coding Style]

http://legacy.python.org/dev/peps/pep-0008/

주요 style 권고들
  • Use 4-space indentation, and no tabs. (들여쓰기는 tab이 아닌 4개의 space)
  • Wrap lines so that they don’t exceed 79 characters. (한줄에 79 영문자 너비)
  • Use blank lines to separate functions and classes, and larger blocks of code inside functions. (한줄 띄우기로 function들, class들 구분)
  • When possible, put comments on a line of their own.
  • Use docstrings.
  • Use spaces around operators and after commas, but not directly inside bracketing constructs: a = f(1, 2) + g(3, 4). (콤마, 뒤에 한칸 띄워라)
  • Name your classes and functions consistently; the convention is to use CamelCase for classes and lower_case_with_underscores for functions and methods. Always use self as the name for the first method argument (see A First Look at Classes for more on classes and methods). (클래스 이름은 붙여서 쓰되 첫글자는 대문자, function/method는 소문자와 '_'의 조합, method들의 첫 argument는 'self'임)
  • Don’t use fancy encodings if your code is meant to be used in international environments. Python’s default, UTF-8, or even plain ASCII work best in any case. (UTF-8 encoding 기본 사용)
  • Likewise, don’t use non-ASCII characters in identifiers if there is only the slightest chance people speaking a different language will read or maintain the code.


[String]

. 짝만 맞으면 ', " 를 혼용해서 사용 가능

>>> 'spam eggs'  # single quotes
'spam eggs'
>>> 'doesn\'t'  # use \' to escape the single quote...
"doesn't"
>>> "doesn't"  # ...or use double quotes instead
"doesn't"
>>> '"Yes," he said.'
'"Yes," he said.'
>>> "\"Yes,\" he said."
'"Yes," he said.'
>>> '"Isn\'t," she said.'
'"Isn\'t," she said.'


[Flow Control]

'{', '}' 가 없고 ':'와 들여쓰기를 사용 함.

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

for each 지원

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

range(start, stop[, step]) 함수가 있어 for문에서 활용 가능

range(5, 10)
   5 through 9

range(0, 10, 3)
   0, 3, 6, 9

range(-10, -100, -30)
  -10, -40, -70

continue, break와는 다르게
아무것도 안하고 넘어가는 pass가 있음
C에서 ';'와 같은...

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


[Function]

'def 함수이름(argument) : '로 시작

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

default argument는 존재하고 사용법 비슷

Arbitrary Argument는 '*'를 argument 앞에 붙임. C는 '...'

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

Lambda 존재

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


[Module]

xxxx.py로 저장을 하고 module의 이름은 __name__ 변수에 저장됨.

> fibo.py

# Fibonacci numbers module

def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

def fib2(n): # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

>>> import fibo

>>> fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'

script로 실행 시 "__main__" 값이 저장되므로
이를 이용해서 스크립트 실행 관련 처리를 할 수 있음.

python fibo.py <arguments>

if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

$ python fibo.py 50
1 1 2 3 5 8 13 21 34

import로는 실행 안됨.

>>> import fibo
>>>


[Scope]

scope를 확인할 수 있는 예제 scope_test()를 실행할 시점에는 global scope에 spam이 없음.
do_local()에서는 scope_test()내의 spam을 수정하는 것이 아니라 do_local()내의 spam을 수정하는 거고 do_nonlocal()에서는 nonlocal이 scope_test()의 spam에 binding을 시킴.
그리고 do_global()의 glocal keyword는 global scope의 spam에 binding 하게 되어 global scope에 spam 변수를 assign?

def scope_test():
    def do_local():
        spam = "local spam"
    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"
    def do_global():
        global spam
        spam = "global spam"
    spam = "test spam"
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)


[class]

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

생성자 : __init__
소멸자 : __del__
모든 method의 첫번째 argument는 self

class Bag:
    def __init__(self):
        self.data = []
    def add(self, x):
        self.data.append(x)
    def addtwice(self, x):
        self.add(x)
        self.add(x)

상속 :
'class child(parent[, parent]*) :'

class DerivedClassName(BaseClassName):
    <statement-1>
    .
    .
    .
    <statement-N>

private variable 없음.
다만 '__'를 붙여서 private 처럼 생각하고 사용하는 방법은 있음.

class Mapping:
    def __init__(self, iterable):
        self.items_list = []
        self.__update(iterable)

    def update(self, iterable):
        for item in iterable:
            self.items_list.append(item)

    __update = update   # private copy of original update() method

class MappingSubclass(Mapping):

    def update(self, keys, values):
        # provides new signature for update()
        # but does not break __init__()
        for item in zip(keys, values):
            self.items_list.append(item)

연산자 오버로딩 :
def __add__(self, other) :



[Exception Handling]

try, except(as) 로 에러를 catch함.
raise로 exception 발생 시킬 수 있음.

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as err:
    print("I/O error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

clean-up 코드를 위한 finally 있음.

>>> try:
...     raise KeyboardInterrupt
... finally:
...     print('Goodbye, world!')
...
Goodbye, world!
KeyboardInterrupt





댓글 없음:

댓글 쓰기