Python byDreamy postedApr 30, 2014

유용한 Python 함수 및 기능들

?

단축키

Prev이전 문서

Next다음 문서

ESC닫기

+ - Up Down Comment Print

출처 : http://pypix.com/tools-and-tips/python-functions/



가변 갯수 인자로 함수 쓰기


우선 다음의 단순한 선택 인자 예제를 보자.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11

def function(arg1="",arg2=""): print "arg1: {0}".format(arg1) print "arg2: {0}".format(arg2) function("Hello", "World") # prints arg1: Hello # prints arg2: World function() # prints arg1: # prints arg2:


함수 인자에 =를 이용하여 default 값을 지정해 놓으면 해당 인자를 명시하지 않을 경우 default 값이 사용된다.


하지만 이보다는 좀 더 유연한 방법도 있다. Tuple을 이용한 인자 받기 방식이다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18

def foo(*args): # "*" 를 사용하면 나머지 인자를 모두 tuple로 받는다. numargs = len(args) print "Number of arguments: {0}".format(numargs) for i, x in enumerate(args): print "Argument {0} is: {1}".format(i,x) foo() # Number of arguments: 0 foo("hello") # Number of arguments: 1 # Argument 0 is: hello foo("hello","World","Again") # Number of arguments: 3 # Argument 0 is: hello # Argument 1 is: World # Argument 2 is: Again



glob()으로 파일 찾기


glob()을 써본 적이 없다면 이름에서 뭘 하는 함수인지 유추해내기는 쉽지 않을 것이다. 일종의 listdir()의 다른 버전이라고 생각하면 될 듯.

이 함수는 이름 패턴을 써서 파일들을 찾는 데에 사용된다.


1
2
3
4
5
6
7
8
import glob
 
# get all py files
files = glob.glob('*.py')
print files
 
# Output
# ['arg.py', 'g.py', 'shut.py', 'test.py']


다음과 같은 방식으로 다양한 파일 타입을 동시에 찾을 수도 있다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import itertools as it, glob
 
def multiple_file_types(*patterns):
    return it.chain.from_iterable(glob.glob(pattern) for pattern in patterns)
 
for filename in multiple_file_types("*.txt", "*.py"): # add as many filetype arguements
    print filename
 
# output
#=========#
# test.txt
# arg.py
# g.py
# shut.py
# test.py


찾은 파일들에 대해 full path를 알고 싶다면 리턴값에 대해 realpath()를 사용하면 된다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
import itertools as it, glob, os
 
def multiple_file_types(*patterns):
    return it.chain.from_iterable(glob.glob(pattern) for pattern in patterns)
 
for filename in multiple_file_types("*.txt", "*.py"): # add as many filetype arguements
    realpath = os.path.realpath(filename)
    print realpath
 
# output
#=========#
# C:\xxx\pyfunc\test.txt
# C:\xxx\pyfunc\arg.py
# C:\xxx\pyfunc\g.py
# C:\xxx\pyfunc\shut.py
# C:\xxx\pyfunc\test.py



디버깅


(물론 pdb로 디버깅하는 방법도 있지만) 아래 예제들은 inspect 모듈을 사용한 것이다. 이 모듈은 디버깅 목적으로 매우 유용하며 많은 것을 얻어낼 수 있다. 아래에 간단한 예제를 명시한다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import logging, inspect
 
logging.basicConfig(level=logging.INFO,
    format='%(asctime)s %(levelname)-8s %(filename)s:%(lineno)-4d: %(message)s',
    datefmt='%m-%d %H:%M',
    )
logging.debug('A debug message')
logging.info('Some information')
logging.warning('A shot across the bow')
 
def test():
    frame,filename,line_number,function_name,lines,index=\
        inspect.getouterframes(inspect.currentframe())[1]
    print(frame,filename,line_number,function_name,lines,index)
 
test()
 
# Should print the following (with current date/time of course)
#10-19 19:57 INFO     test.py:9   : Some information
#10-19 19:57 WARNING  test.py:10  : A shot across the bow
#(<frame object at 0x01E8A390>, 'C:/xxx/pyfunc/magic.py', 16, '<module>', ['test()\n'], 0)



단일 ID 생성


뭔가 ID 역할을 할 문자열을 생성해야 할 상황에 부딪치는 경우가 많을 것이다. 많은 사람들이 그런 경우에 md5()를 쓰는 것을 보았는데 정확한 해결책이라고는 할 수 없다.


그런 목적을 위해서는 파이썬에서 지원하는 uuid()가 더 적합하다.


1
2
3
4
5
6
7
8
import uuid
result = uuid.uuid1()
print result
 
# output => various attempts
# 9e177ec0-65b6-11e3-b2d0-e4d53dfcf61b
# be57b880-65b6-11e3-a04d-e4d53dfcf61b
# c3b2b90f-65b6-11e3-8c86-e4d53dfcf61b


생성된 문자열들이 각각 다르기는 해도 뒷부분은 동일하다는 것을 눈치챘는지? 이는 uuid가 네트웍 주소에 기반하기 때문이다.


중복여지를 더 줄이기 위해서는 다음과 같은 방식도 쓸 수 있다.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import hmac,hashlib
key='1'
data='a'
print hmac.new(key, data, hashlib.sha256).hexdigest()
 
m = hashlib.sha1()
m.update("The quick brown fox jumps over the lazy dog")
print m.hexdigest()
 
# c6e693d0b35805080632bc2469e1154a8d1072a86557778c27a01329630f8917
# 2fd4e1c67a2d28fced849ee1bb76e7391b93eb12



직렬화


DB나 텍스트 파일에 복잡한 변수를(객체 변수) 저장해야 되었던 적이 있었는지? 그런 경우에 굳이 특정 포맷의 문자열을 생성한다든가 할 필요는 없다. 파이썬은 이미 그런 목적을 위한 함수들을 갖고 있다.


 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
29
30
import pickle
 
variable = ['hello', 42, [1,'two'],'apple']
 
# serialize content
file = open('serial.txt','w')
serialized_obj = pickle.dumps(variable)
file.write(serialized_obj)
file.close()
 
# unserialize to produce original content
target = open('serial.txt','r')
myObj = pickle.load(target)
 
print serialized_obj
print myObj
 
#output
# (lp0
# S'hello'
# p1
# aI42
# a(lp2
# I1
# aS'two'
# p3
# aaS'apple'
# p4
# a.
# ['hello', 42, [1, 'two'], 'apple']


이는 파이썬 고유의 직렬화 방법이다(즉 파이썬에서만 읽을 수 있음). 하지만 최근에는 JSON 포맷이 인기를 끌다 보니 그에 대한 것도 지원하게 되었다.

이제 JSON으로 인코딩/디코딩하는 예제를 보자.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
import json
 
variable = ['hello', 42, [1,'two'],'apple']
print "Original {0} - {1}".format(variable,type(variable))
 
# encoding
encode = json.dumps(variable)
print "Encoded {0} - {1}".format(encode,type(encode))
 
#deccoding
decoded = json.loads(encode)
print "Decoded {0} - {1}".format(decoded,type(decoded))
 
# output
 
# Original ['hello', 42, [1, 'two'], 'apple'] - <type 'list'>
# Encoded ["hello", 42, [1, "two"], "apple"] - <type 'str'>
# Decoded [u'hello', 42, [1, u'two'], u'apple'] - <type 'list'>


이는 훨씬 간단하면서도 javascript나 다른 언어와도 호환이 가능하다.

하지만 복잡한 객체들의 경우 일부 정보가 유실될 수도 있으므로 주의해서 사용해야 한다.



문자열 압축


압축에 대해 얘기하면 보통 ZIP 파일 같은 것들을 생각하겠지만 파이썬에서는 그런 압축 파일을 생성하지 않고도 압축을 지원한다.


 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
29
30
31
32
import zlib
 
string =  """   Lorem ipsum dolor sit amet, consectetur
                adipiscing elit. Nunc ut elit id mi ultricies
                adipiscing. Nulla facilisi. Praesent pulvinar,
                sapien vel feugiat vestibulum, nulla dui pretium orci,
                non ultricies elit lacus quis ante. Lorem ipsum dolor
                sit amet, consectetur adipiscing elit. Aliquam
                pretium ullamcorper urna quis iaculis. Etiam ac massa
                sed turpis tempor luctus. Curabitur sed nibh eu elit
                mollis congue. Praesent ipsum diam, consectetur vitae
                ornare a, aliquam a nunc. In id magna pellentesque
                tellus posuere adipiscing. Sed non mi metus, at lacinia
                augue. Sed magna nisi, ornare in mollis in, mollis
                sed nunc. Etiam at justo in leo congue mollis.
                Nullam in neque eget metus hendrerit scelerisque
                eu non enim. Ut malesuada lacus eu nulla bibendum
                id euismod urna sodales. """
 
print "Original Size: {0}".format(len(string))
 
compressed = zlib.compress(string)
print "Compressed Size: {0}".format(len(compressed))
 
decompressed = zlib.decompress(compressed)
print "Decompressed Size: {0}".format(len(decompressed))
 
# output
 
# Original Size: 1022
# Compressed Size: 423
# Decompressed Size: 1022



나눔글꼴 설치 안내


이 PC에는 나눔글꼴이 설치되어 있지 않습니다.

이 사이트를 나눔글꼴로 보기 위해서는
나눔글꼴을 설치해야 합니다.

설치 취소

Designed by sketchbooks.co.kr / sketchbook5 board skin

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5

Sketchbook5, 스케치북5