행복한 아빠

Python의 숨은? 특징 2 본문

Python

Python의 숨은? 특징 2

행복한아빠 2016. 8. 30. 14:29

지난 번에 이어 알아둘 만하거나 재미있는 파이썬의 특징을 정리합니다. 지난 번 포스트는 여기로

알아보면 알아볼 수록 재미있고 매력적입니다.





예외 재발생


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Python 2 syntax
try:
    some_operation()
except SomeError, e:
    if is_fatal(e):
        raise
    handle_nonfatal(e)
 
# Python 3 syntax
try:
    some_operation()
except SomeError as e:
    if is_fatal(e):
        raise
    handle_nonfatal(e)
cs


에러 핸들러 안에서 인자없이 사용한 raise는 원래의 예외를 다시 던지라는 뜻입니다. "미안 난 이 예외를 잡을 수 없어요"라고 말할 수 있게 하죠.

원래의 traceback을 출력, 저장 또는 뭔가 하려면 sys.exc_info()를 사용하여 'traceback' 모듈에서 하는 것처럼 출력할 수 있습니다.



내장객체 set 의 연산자 재정의

다음과 같이 set은 다양한 연산을 지원합니다.

1
2
3
4
5
6
7
8
9
10
11
12
>>> a = set([1,2,3,4])
>>> b = set([3,4,5,6])
>>> a | b # Union
{123456}
>>> a & b # Intersection
{34}
>>> a < b # Subset
False
>>> a - b # Difference
{12}
>>> a ^ b # Symmetric Difference
{1256}
cs

파이썬 2.7 또는 3.0에서는 set을 중괄호로 생성할 수 있습니다.


1
myset = {1,2,3,4}
cs


자세한 내용은 여기에서



Negative round

round() 함수는 주어진 정밀도로 float 수를 반올림합니다. 정밀도는 음수가 될 수 있습니다.

1
2
3
4
>>> str(round(1234.5678-2))
'1200.0'
>>> str(round(1234.56782))
'1234.57'
cs


Note) float는 정확한 값을 계산하지 못합니다. 정확한 값을 계산하려면 decimal모듈의 Decimal을 사용하세요.



문자열과 boolean 곱셈

웹개발을 하면서 계속되는 일 중 하나가 HTML 파라메터를 선택적으로 출력하는 일입니다. 다른 언어에서는 다음과 같이 해 왔습니다.

class='<% isSelected ? "selected" : "" %>'


파이썬에서는 boolean을 곱하여 기대할 수 있는 결과를 얻을 수 있습니다.


class='<% "selected" * isSelected %>'


boolean을 강제로 곱하면 정수형(False는 0, True는 1)으로 바뀌기 때문인데, 파이썬에서 문자열에 정수 n을 곱하면 정수 n만큼 문자열이 반복됩니다. 다음 코드 실행해 보세요.


'abc' * 3



re는 함수를 호출할 수 있다.

문자열이 정규식에 매칭될 때마다 함수를 호출하는 기능도 매우 유용하다. 여기에 "Hello"를 "Hi,"로, "there"를 "Fred" 등으로 교체하는 예제를 보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import re
 
def Main(haystack):
  # List of from replacements, can be a regex
  finds = ('Hello''there''Bob')
  replaces = ('Hi,''Fred,''how are you?')
 
  def ReplaceFunction(matchobj):
    for found, rep in zip(matchobj.groups(), replaces):
      if found != None:
        return rep
 
    # log error
    return matchobj.group(0)
 
  named_groups = [ '(%s)' % find for find in finds ]
  ret = re.sub('|'.join(named_groups), ReplaceFunction, haystack)
  print ret
 
if __name__ == '__main__':
  str = 'Hello there Bob'
  Main(str)
  # Prints 'Hi, Fred, how are you?'
cs


매칭된 값을 정규식이 아니라 내가 정의한 임의의 함수로 바꿀 수 있습니다. 와우~



파이썬 3에서 튜플 unpacking

파이썬 3에서 함수 선언의 튜플 unpacking과 같은 선택적 아규먼트 구문을 할당문에 사용할 수 있습니다.

1
2
3
4
5
6
7
>>> first,second,*rest = (1,2,3,4,5,6,7,8)
>>> first
1
>>> second
2
>>> rest
[345678]
cs


덜 알려진 기능으로 리스트의 중간에 정해지지 않은 개수의 리스트를 할당할 수 있습니다.


1
2
3
4
5
6
7
>>> first,*rest,last = (1,2,3,4,5,6,7,8)
>>> first
1
>>> rest
[234567]
>>> last
8
cs



다중 라인 문자열

여러 라인의 문자열을 처리하기 위해 한 방법으로 백슬러시를 사용합니다.

1
2
3
4
>>> sql = "select * from some_table \
where id > 10"
>>> print sql
select * from some_table where id > 10
cs


다른 방법으로는 쌍따옴표 3개를 사용하는 방법이 있습니다.


1
2
3
4
 >>> sql = """select * from some_table 
where id > 10"""
>>> print sql
select * from some_table where id > 10
cs


위 방법들은 들어쓰기가 안되어 보기 싫은 코드가 되네요. 이 방법으로 들여쓰기 하면 공백이 추가될 것입니다.


세번째 방법으로 문자열을 나누고 아래와 같이 괄호를 쓰는 방법입니다.


1
2
3
4
5
>>> sql = ("select * from some_table " # <-- no comma, whitespace at end
           "where id > 10 "
           "order by name"
>>> print sql
select * from some_table where id > 10 order by name
cs


여기에서 콤마(,)는 없어야 합니다(튜플이 아닙니다). 이러면 앞뒤로 필요한 공백을 추가할 수 있습니다.  이것은 "my name is %s" % name 과 같은 placeholder에서도 작동합니다.



Interpreter에서 밑줄

Interpreter에서 밑줄(_)은 최근 출력된 값을 담습니다.


1
2
3
4
5
>>> (a for a in xrange(10000))
<generator object at 0x81a8fcc>
>>> b = 'blah'
>>> _
<generator object at 0x81a8fcc>
cs



편리한 웹브라우저 컨트롤러

다음과 같이 웹브라우저를 컨트롤할 수 있습니다.


1
2
>>> import webbrowser
>>> webbrowser.open_new_tab('http://www.stackoverflow.com')
cs



내장된 HTTP 서버

현재 디렉토리의 파일을 서비스 하려면...


python -m SimpleHTTPServer 8000



AtExit

인터프리터를 종료할 때 호출해야 함수를 등록할 수 있습니다.


1
2
3
4
5
6
7
8
9
>>> def exit_handler():
...     print 'bye'
... 
>>> import atexit
>>> atexit.register(exit_handler)
<function exit_handler at 0x106bd2cf8>
>>> quit()
bye
 
cs



pow() 함수 세번째 인자

내장 pow(x, y, z) 함수의 세번째 인자는 x의 y승 값을 z로 나눈 나머지 값을 구하는 역할을 효율적으로 합니다. 즉 (x ** y) % z 와 같은 값을 구합니다.


1
2
3
>>> x, y, z = 1234567890234567890117
>>> pow(x, y, z)            # almost instantaneous
6
cs


위의 경우 (x ** y) % z 수식으로 구하면 시간이 오래 걸립니다. pow()로 구하면 바로 결과가 나옵니다.


Unzip

Zip은 동일한 개수의 리스트를 묶어줍니다. 반대로 원래 데이터를 구하기 위해서 다음과 같이 할 수 있습니다.

1
2
3
>>> a = [(1,2), (3,4), (5,6)]
>>> zip(*a)
[(135), (246)]
cs


enumerate에서 다른 번호로 index 시작하기

enumerate를 이용하면 0부터 시작하는 index를 사용할 수 있습니다. 0이 아니라 다른 번호로 index를 시작하려면 두번째 인자를 주어 다음과 같이 할 수 있습니다.

1
2
3
4
5
>>> my_list = ["spam""ham""eggs"]
>>> list(enumerate(my_list))
>>> [(0"spam"), (1"ham"), (2"eggs")]
>>> list(enumerate(my_list, 1))
>>> [(1"spam"), (2"ham"), (3"eggs")]
cs



property 클래스

property 클래스로 여러분의 클래스 인터페이스를 좀 더 엄격히 만들 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class C(object):
    def __init__(self, foo, bar):
        self.foo = foo # read-write property
        self.bar = bar # simple attribute
 
    def _set_foo(self, value):
        self._foo = value
 
    def _get_foo(self):
        return self._foo
 
    def _del_foo(self):
        del self._foo
 
    # any of fget, fset, fdel and doc are optional,
    # so you can make a write-only and/or delete-only property.
    foo = property(fget = _get_foo, fset = _set_foo,
                   fdel = _del_foo, doc = 'Hello, I am foo!')
 
class D(C):
    def _get_foo(self):
        return self._foo * 2
 
    def _set_foo(self, value):
        self._foo = value / 2
 
    foo = property(fget = _get_foo, fset = _set_foo,
                   fdel = C.foo.fdel, doc = C.foo.__doc__)
cs

파이썬 2.6 이상이나 3.0이상에서는 다음과 같이 사용할 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 class C(object):
    def __init__(self, foo, bar):
        self.foo = foo # read-write property
        self.bar = bar # simple attribute
 
    @property
    def foo(self):
        '''Hello, I am foo!'''
 
        return self._foo
 
    @foo.setter
    def foo(self, value):
        self._foo = value
 
    @foo.deleter
    def foo(self):
        del self._foo
 
class D(C):
    @C.foo.getter
    def foo(self):
        return self._foo * 2
 
    @foo.setter
    def foo(self, value):
        self._foo = value / 2
cs



내장된 코덱 base64, zlib, rot13

String은 encode와 decode 메소드를 가지고 있습니다. 보통 u = s.encode('utf8')과 같이 문자코드 변환하는데 사용되지만 여기에 유용한 내장 코덱이 있습니다. import 없이 zlib으로 압축, 압축풀기도 할 수 있습니다.

1
2
3
>>> s = 'a' * 100
>>> s.encode('zlib')
'x\x9cKL\xa4=\x00\x00zG%\xe5'
cs

유사하게 base64 인코딩, 디코딩도 할 수 있습니다.

1
2
3
4
>>> 'Hello world'.encode('base64')
'SGVsbG8gd29ybGQ=\n'
>>> 'SGVsbG8gd29ybGQ=\n'.decode('base64')
'Hello world'
cs

물론 rot13 인코딩, 디코딩도 가능합니다.

1
2
 >>> 'Secret message'.encode('rot13')
'Frperg zrffntr'
cs


후~ 뭐 계속 있기는 한데 여기까지만...

재미있는 것은 이런 것들이 유용한가 유용하지 않을가를 떠나서 하나 하나 정확히 알아보면 파이썬에 대한 이해가 깊어지는 것 같습니다.


뭐 그렇다는...

'Python' 카테고리의 다른 글

Ubuntu에 장고 애플리케이션 배포  (0) 2016.10.07
Python의 숨은? 특징 2  (0) 2016.08.30
Python의 숨은? 특징 (어머 이건 사야 돼)  (0) 2016.08.25
0 Comments
댓글쓰기 폼