새소식

AI 개발

[Python] Effective Python 1 - call by assignment

  • -

 

 

내가 맨 처음에 파이썬을 좋아했던 이유는

코드를 짧게 쓸 수 있어서였다.

 

다른 언어로 하면 길어지는 코드를 한 줄로 만들 수 있는 경우가 되게 많았다.

enumerate, zip 함수와 map, 리스트를 생성하는 동시에 for 문을 돌려버린다던지.. 하는 것들

 

뭔가 다른 언어들과 다른 느낌의 무언가가 굉장히 맘에 들었는데,

깔끔하고 정갈하고 독특하고 자유로운 그런 느낌

 

같은 문제를 풀어도 10명이면 7명은 코드를 다르게 짠다..

그만큼 확장성이 좋고 개인적인 skeleton 코드를 가지기 좋은 언어라고 생각.

 

 

그치만 이렇게 코드를 짧고 간결하게 만들 수 있는데 만족하며

파이썬 언어 자체에 대한 컨셉의 이해도가 낮은 것 같아서 책을 한권 구입함.

 

Effective Python : 파이썬 코딩의 기술

 

주로 파이썬은 파이썬 답게 써야 하는 이유를 알려주는 책이다.

파이썬이 어떻게 이러한 특징을 가지게 됬는지,

이러한 특징들로 인해 나는 어떻게 코딩을 해야 하는지 등등

 

정말 재밌고 동시에 은근히 어렵다.

 

오늘부터 여기서 배운 내용들을 하나씩 포스팅 하겠슴다

 

> import this

The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

 

Explicit is better than implicit

 


 

 

Call-by-Assignment

파이썬의 함수 호출 방식은 Call-by-Assignment이다.

 

먼저 Call-by-reference

함수 호출시 인자로 전달되는 변수의 레퍼런스를 전달한다.

인자로 전달된 레퍼런스를 함수 내부에서 실제 값이 반영되며 C언어의 포인터가 대표적인 예시다.

따라서 실제 값이 바뀌면 인자로 전달된 값도 바뀐다.

 

Call-by-value

함수 호출시 전달되는 변수의 값을 복사해서 함수의 인자로 전달된다.

따라서 함수 안에서 인자 값이 변경되도 전달한 외부 변수에는 영향이 가지 않는다.

 

그리고 파이썬은 call-by-reference도 call-by-assignment도 아닌

call-by-assignment 방식으로 인자를 전달한다.

 

파이썬에는 모든 것이 객체이고 2가지의 객체가 있다.

 

1. immnutable object

변경 불가능한 객체라는 뜻으로 일반적인 자료형인 int, float, str과 tuple이 있다.

>>> a = 1
>>> id(a)
140729439544144
>>> a += 1
>>> id(a)
140729439544176

>>> lis = (1, 2)
>>> lis2 = lis
>>> lis == lis2
True
>>> lis2 = (3,)
>>> lis == lis2
False

immutable 객체는 값이 변경되면 객체 자체가 변경되며,

여기에 속한 객체는 call-by-value 이다.

따라서 변수를 복사 할 때 새로운 객체가 생성되며 변경이 일어날 때 기본 객체는 변하지 않는다.

 

 

2. mutable object

변경 가능한 객체라는 뜻으로 list, dictionary, set이 있다.

>>> lis = [1,2]
>>> id(lis)
1985209849032
>>> lis.append(3)
>>> id(lis)
1985209849032

>>> lis2 = lis
>>> lis2 == lis
True
>>> lis2.append(4)
>>> lis == lis2
True

mutable 객체는 값이 변경되면 주소가 참조하는 값이 모두 변경되며,

여기에 속한 객체는 call-by-reference 이다.

따라서 변수를 복사할 때 주소가 참조하는 값이 모두 변경된다.

 

파이썬은 모든 것이 객체이고 또 하나의 객체는 단 하나의 인스턴스로 존재한다. (싱글톤 패턴)

인스턴스를 생성할 때마다 해당 객체에 Reference Count가 하나씩 증가한다.

 

 

 

def func(x):
    x += 10
    return x

x = 1
print(func(x)) # 11
print(x) # 1

여기서 x 는 int이므로 immutable 객체이다.

immutable 객체가 함수의 argument로 전달되면 처음에는 call-by-reference로 받고,

값이 변경되면 call-by-value로 동작한다.

 

def func2(lis):
    lis.append(3)
    return lis
   
lis = [1,2]
print(func2(lis)) # [1,2,3]
print(lis) # [1,2,3]

여기서 lis는 리스트이므로 mutable 객체이다.

mutable  객체가 함수의 argument로 전달되면 call-by-reference 방식으로 함수가 호출된다.

lis의 object reference가 전달되므로 값을 변경하면 actual parameter의 값도 변경된다.

 

 

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.