개발자식

[Python] 함수(function)와 변수(variable) 본문

Data/Python

[Python] 함수(function)와 변수(variable)

밍츠 2022. 9. 22. 03:55

DAY 3

파이썬의 함수, 변수 헷갈렸던 개념을 정리해보자 (특히 메모리 참조 부분!)


함수 호출 방식

- 함수에서 파라미터를 전달하는 방식

  • Call by Value
  • Call by Reference
  • Call by Object Reference

결론부터 얘기하면 파이썬은 Call by Object Reference 방식이다.

 

Call by Value

- 함수에 인자를 넘길 때 값만 넘긴다.

- 함수 내에 인자 값 변경 시, 호출자에게 영향을 주지 않음

 

Call by Reference

- 함수에 인자를 넘길 때 메모리 주소를 넘긴다.

- 함수 내에 인자 값 변경 시, 호출자의 값도 변경됨

 

Call by Object Reference

- 객체의 주소가 함수로 전달되는 방식

- 전달된 객체를 참조하여 변경 시 호출자에게 영향을 주나, 새로운 객체를 만들 경우 호출자에게 영향을 주지 않는다.

 

def f(temp):
    temp.append(1)
    temp = [2, 3]


arr = [0]
f(arr)
print(arr) # [0, 1]

temp는 arr 메모리를 가리켜 기존 객체의 주소 값(arr)에 1 추가,

temp = [2, 3] 명령어로 [2, 3]을 저장하는 새로운 객체를 생성한다. temp는 더 이상 arr의 메모리를 가리키지 않고 새로운 객체를 가리킨다.

 

 

swap

- 함수를 통해 변수 간의 값을 교환하는 함수이다.

def swap_value(x, y):
    temp = x
    x = y
    y = temp
    
    
def swap_offset(offset_x, offset_y):
    temp = a[offset_x]
    a[offset_x] = a[offset_y]
    a[offset_y] = temp
    

def swap_reference(list, offset_x, offset_y):
    temp = list[offset_x]
    list[offset_x] = list[offset_y]
    list[offset_y] = temp
    
a = [1,2,3,4,5]
swap_value(a[1], a[2])
print(a) #[1,2,3,4,5]

swap_offset(1, 2)
print(a) #[1,3,2,4,5]

swap_reference(a, 3, 4)
print(a)#[1,3,2,5,4]

- swap_offset : 리스트의 전역 변수 값을 직접 변경한다.

- swap_reference : 리스트 객체의 주소 값을 받아 값을 변경한다.

- 위에서 언급한 call by~ 를 설명하는 전통적인 함수 예시이다.

 

변수의 범위 (Scoping Rule)

- 변수가 사용되는 범위를 말한다. 여기서 범위는 함수 또는 메인 프로그램이다.

  • 지역 변수 (local variable) : 함수내에서만 사용
  • 전역 변수 (global variable) : 프로그램 전체에서 사용 (함수 포함)
def test(t):
    t = 20
    print("In test function : ", t)
 
 
def test1(t):
    print("In test function : ", t)    
    
    
x = 10

test(x) #In test function : 20
test1(x) #In test function : 10

위의 코드에서 test 함수, test1 함수에 작성된 t는 지역 변수이고, 아래 x는 전역 변수이다. 여기서 중요한 점은,

  • test(x)가 호출되면 t는 x와 같은 메모리를 가리키다가 t = 20 명령어로 인해 t는 20을 저장하는 새로운 메모리를 가리켜, 20을 출력한다.
  • test 1(x)가 호출되면 t는 x와 같은 메모리를 가리키기 때문에, 10을 출력한다.

 

def f():
    s = "I love London!"
    print(s)


s = "I love Paris!"
f() #I love London!
print(s) #I love Paris!

함수 내에 전역 변수와 같은 이름의 변수를 선언하면 새로운 지역 변수가 생긴다. (함수에서 사용 가능!)

함수 내에서 전역변수를 사용하려면?? global 키워드를 사용한다. 아래 코드 참고!

 

def f():
    global s
    s = "I love London!"
    print(s)


s = "I love Paris!"
f() #I love London!
print(s) #I love London!

 

결론

- 전역변수와 같은 변수명으로 함수에서 사용해도 새로운 값이 할당되면 그 변수는 새로운 지역변수가 된다

- 전역변수를 함수 내에서 사용하려면 global 키워드를 사용한다.

 

 

동적 타이핑(dynamic typing)

- 파이썬의 가장 큰 특징은 동적 타이핑(dynamic typing)이다.

- typing : 프로그램 내에서 변수의 데이터 타입을 정의하는 것

  • 정적 타이핑 (static typing) : 변수의 데이터 타입을 미리 선언하는 방식
  • 동적 타이핑 (dynamic typing) : 변수의 데이터 타입 미리 선언하지 않아도 자동으로 메모리 공간 할당하는 방식

하지만 처음 함수를 사용하는 사용자가 interface를 알기 어렵다는 단점이 있다.

-> python 3.5 버전 이후로는 PEP 484에 기반하여 type hints 기능을 제공한다.

def do_function(var_name : var_type) -> return_type:
    pass

var_type : 변수 데이터 타입

return_type : 리턴 데이터 타입

 

type hints 장점

- 사용자에게 인터페이스를 명확히 알려줄 수 있다.

- 함수의 문서화 시 파라미터에 대한 정보를 명확히 알 수 있다.

- mypy 또는 IDE, linter 등을 통해 코드의 발생 가능한 오류를 사전에 확인한다.

- 시스템 전체적인 안정성을 확보할 수 있다.

 

function docstring

- 파이썬 함수에 대한 상세 스펙을 사전에 작성하여 사용자의 이해도를 높인다.

- 함수명 아래에 세 개의 따옴표로 docstring 영역을 표시한다.

- 목적, 파라미터 설명, 리턴 설명, 예시의 형태로 일반적으로 작성한다.

+vscode에서 docstring을 설치하고 ctrl+shift+p를 눌러 docstring을 검색하면 자동으로 docstring을 작성해준다.

(전에 팀 프로젝트에서 팀원분께서 이렇게 코드 작성해주셔서 이해하기 쉬웠던 기억이..!)

 

함수 작성 가이드라인

- 함수는 가능하면 짧게 작성할 것

- 함수 이름에 함수의 역할, 의도가 명확히 들어낼 것, 동사+목적어 형태 ex) print_hello_world() 

- 하나의 함수에는 유사한 역할을 하는 코드만 포함하기 (함수 구분!)

- 인자로 받은 값 자체를 바꾸진 말 것 (복사하기!)

 

함수를 언제 만드는 게 좋을까?

- 공통적으로 사용되는 코드는 함수로 변환

- 복잡한 수식일 때

- 복잡한 조건일 때

 

코드를 짜는 것은 팀 프로젝트로 사람의 이해를 돕기 위해 규칙이 필요하다.

이를 파이썬 코딩 컨벤션(PEP8)이라고 한다.

 

파이썬 코딩 컨벤션

- 명확한 규칙은 없음

- 때로는 팀마다, 프로젝트마다 따로

- 중요한 건 일관성

- 문서 작성하듯이 읽기 좋은 코드가 좋은 코드

- 들여 쓰기는 tab 보다 공백 4칸 권장 (섞어 쓰지 말기)

- 한 줄은 최대 79자까지 (옛날 모니터의 크기 때문에)

- 불필요한 공백은 피함

- 함수 사이에 2칸 뛰기

- =연산자는 1칸 이상 안 띄움

- 주석은 항상 갱신, 불필요한 주석은 삭제

- 코드의 마지막에는 항상 한 줄 추가

- 소문자 I, 대문자 O, 대문자 I 금지 (가독성 떨어짐)

- 함수명은 소문자로 구성, 필요하면 밑줄로 나눔

 

파이썬 코딩 컨벤션에 맞게 잘 작성했는지 확인하는 방법 : flake8 모듈

- conda install flake8로 설치

- flake8 파일명.py로 실행

-> 어디를 고쳐야 할지 상세하게 출력

 

파이선 코딩 컨벤션에 맞게 자동으로 수정해주는 방법 : black 모듈

- conda install black로 설치

- black 파일명.py로 실행

 

 

회고

클린 코드에 관심이 많았는데 함수 작성 시 알아야 되는 기본 코딩 방식에 대해 알게 되어서 좋다.

코딩하면서 대충 알고 있었던 파이썬의 큰 특징인 함수 호출 방식에 대해 정리할 수 있었다!!

 

 

Comments