Python tutorial for Rubyist

January 08, 2017

이 글은 파이썬 3에 뛰어들기를 읽으며 배운 문법에 대해서 정리했습니다. 평범하게 정리하면 재미가 없기 때문에, 루비 개발자가 보았을때 낯설어보일 수 있는 부분을 중점적으로 정리해봤습니다.

Function argument

# Success to call
approximate_size(4000, a_kilobyte_is_1024_bytes=False)
approximate_size(size=4000, a_kilobyte_is_1024_bytes=False)
approximate_size(a_kilobyte_is_1024_bytes=False, size=4000)

# SyntaxError
approximate_size(a_kilobyte_is_1024_bytes=False, 4000)
approximate_size(size=4000, False)

Docstring

document = '''
query {
  task
}
'''
document # => '\nquery {\n  task\n}\n'

Ternary Operator

파이썬에는 일반적으로 많이 사용하는 삼항 연산자가 없습니다. 대신 다음과 같이 작성할 수는 있습니다.

value = True if condition else False

in

some_list = ['el', 'em', 'ent']
'el' in some_list # => True

## 열거 가능
for e in some_list:
    print(e)

List

Tuple

one_element_tuple = (1,)
some_tuple = (1, 2, 3)
some_tuple.append(4)
## AttributeError: 'tuple' object has no attribute 'append'

Set

a_set = {1}
a_set = set([1])
it_is_dict = {}
it_is_set = set()

Comprehension

a_list = [1, 2, 3, 4]
[elem * 2 for elem in a_list] # => [2, 4, 6, 8]

a_set = {1, 2, 3, 4}
{elem * 2 for elem in a_set} # => {8, 2, 4, 6}

a_dict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
{key:value * 2 for key, value in a_dict.items()} # => {'a': 2, 'b': 4, 'c': 6, 'd': 8}

String

Regexp

s = '100 BROAD'
re.sub('\\bROAD$', 'RD.', s)
re.sub(r'\bROAD$', 'RD.', s)
pattern = '''
    ^                   # 문자열의 시작
    M{0,3}              # 천의 자리 - 0-3 개의 M
    (CM|CD|D?C{0,3})    # 백의 자리 - 900(CM), 400(CD), 0-300(0-3 개의 C),
                        #           500-800(D 하나와, 뒤이은 0 to 3 개의 C)
    (XC|XL|L?X{0,3})    # 십의 자리 - 90(XC), 40(XL), 0-30(0-3 개의 X),
                        #           50-80(L 하나와, 뒤이은 0-3 개의 X)
    (IX|IV|V?I{0,3})    # 일의 자리 - 9(IX), 4(IV), 0-3(0-3 개의 I),
                        #           5-8(V 하나와 뒤이은 0-3 개의 I)
    $                   # 문자열의 끝
    '''
re.search(pattern, 'M', re.VERBOSE)

Generator

def fib(max):
    a, b = 0, 1
    while a < max:
        yield a
        a, b = b, a + b

[f for f in fib(10)]
list(fib(10))

# Generator Expression
unique_characters = {'E', 'D', 'M', 'O', 'N', 'S', 'R', 'Y'}
gen = (c for c in unique_characters)

next(gen) # => 'E'
next(gen) # => 'D'

Class

class AClass:
    def __init__(self, attr):
        self.attr = attr

    def this_is_an_instance_method(self):
        return 'Hoge'

    def this_is_a_class_method():
        return 'Hige'

    def __this_is_a_private_instance_method(self):
        pass

ins = AClass('some attr')
ins.this_is_an_instance_method()
AClass.this_is_a_class_method()

Iterator

class Fib:
    def __init__(self, max):
        self.max = max

    def __iter__(self):
        self.a = 0
        self.b = 1
        return self

    def __next__(self):
        fib = self.a
        if fib > self.max:
            raise StopIteration
        self.a, self.b = self.b, self.a + self.b
        return fib

for n in Fib(1000):
    print(n, end=' ')
## 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987

Etc