[wecode 8일차] - Scope

hyuckhoon.ko·2020년 6월 1일
0

What I learned in wecode

목록 보기
37/109

1. Scope

1. local scope

Local scope을 가지고 있는 변수, 함수 혹은 객체는
특정 범위(local)에서만 유효하다.

    def func(variable):
        return variable
        
    variable = func(5)
    print(variable)

func함수의 parameter인 variable
func함수의 리턴값을 저장하는 variable는 이름은 같으나 서로 다른 변수다.

즉,

def func(variable):
    return variable

에서 변수 variable이 유효한 범위는 함수 정의 부분에 한한다.


2. Enclosing Scope

중첩함수가 있을때 적용되는 scope입니다. 부모 함수에서 선언된 변수는
중첩함수 안에서도 유효한 범위를 가지고 있다.

def outer_func(msg):
  def inner_func():
      print(f'{msg}')
  return inner_func

msg_print = outer_func("Encolsing scope입니다.")
msg_print()

outer_func 안에 inner_func가 있는 중첩 함수 구조다.

< 참고 >

  • 부모함수 : outer_func
  • 자식함수 : inner_func ( = 중첩함수 )

중첩함수는 부모함수의 변수를 사용할 수 있다.

위의 코드를 보면 부모함수의 msg
중첩함수 inner_func가 매개변수로 받지 않고 바로 출력하고 있다.



3. Global scope

Global scope란,
함수 에서 선언된 변수나 함수의 영역을 말한다.
변수나 함수는 선언된 지점과 동일한 level의 지역 및
더 안쪽의 지역들까지 범위가 유효합니다.

변수, 함수 및 객체가 가장 바깥쪽에서 선언되므로 해당 파일에서 선언된 지점 아래로는 다 유효한 범위를 가진다.

# 가장 바깥에 선언된 Global 변수
pi = 3.14

def outer_func(radius):
    def decorator_func(original_func):
        def wrapper_func():
            # 중첩함수에서도 Global 변수 출력 가능
            print(f"중첩함수에서도 출력가능 : {pi}")
            print(original_func(radius))
        return wrapper_func
    return decorator_func

@outer_func(5)
def get_circle(radius):
	# 로컬함수에도 Global 변수 출력 가능
    print(f"로컬 영역의 함수에서도 출력가능 : {pi}")
    return pi * (radius ** 2)
get_circle()


4. Built-in Scope

Built-in scope은 scope중 가장 광범위한 scope다.
(모든 파이썬 파일에서 유효한 범위를 가진다.)
파이썬 내장함수 또는 속성(attribute)들이 built-in scope를 가지고 있다.
built-in 되어 있으모로 따로 선언할 필요가 없다.

Ex) element 총 개수를 리턴하는 len (내장)함수



2. Class

풀리지 않는 클래스 관련 문제를
무려 6시간을 디버깅, 구글링, 마인드맵 동원.....
마지막에 동기분께 물어봐서 해결할 수 있었다.
(클래스 개념 때문에 에러가 난 것이 아니었다.....)


Q. Database 라는 이름의 class를 구현하시오.
Database 클래스는 다음의 속성(attribute)들을 가지고 있습니다.

  • name : database의 이름
  • size : 저장할 수 있는 데이터의 max 사이즈. Size를 넘는 데이터 를 저장할 수 없음.
    [ Database 클래스는 다음의 메소드들을 가지고 있습니다. ]
  • insert
  • select
  • update
  • delete

6시간 동안 나를 붙잡아 둔 부부은 insert 메소드의 구현이었다.
insert메소드의 조건은 다음과 같았다.

[ 조건 ]

"만일 내부 dictionary의 총 사이즈가 database 클래스의 size 속성보다 크면 더이상 새로운 값들을 저장하지 말아야 한다"

1) '사이즈'니까 (바이트)크기를 묻는건가? 싶어서

import sys
if not sys.getsizeof(self.my_dict)  > sys.getsizeof(self.size)
	self.my_dict[field] = value

그러나 딕셔너리 자료구조의 크기가 언제나 컸다.
위의 코드처럼 작성하면 아무런 값도 insert되지 않는다.

2) 인스턴스 변수말고 클래스 변수로 사용해야하나?

아니면 딕셔너리를 global scope에 넣어야 하나?

둘 다 시도했고, 변화는 없었다.

3) 문법 표현을 바꿔보기도 했다. 예를 들어,

if field in self.my_dict:
    return(self.my_dict[field])

if field in self.my_dict.keys():
    return(self.my_dict[field])

로 말이다.

하지만 결과는 같았다.


4) 결국 해결책은 '대소 관계' 에 대한 해석 문제였다.

[ 조건 ]

"만일 내부 dictionary의 총 사이즈가 database 클래스의 size 속성보다 크면 더이상 새로운 값들을 저장하지 말아야 한다"

if not len(self.dictionary) >= self.size:
    self.my_dict[field] = value

혹은

if len(self.dictionary) < self.size:
    self.my_dict[field] = value

이 정답이었다.

하지만 사실 조건 부분에서 수정해야 할 내용이 있다.

~ 속성보다 크거나 같은 경우 라고 수정해야 한다.
"같은 경우"라는 말을 추가하느냐 마느냐에 따라
결과가 달라질 수 있다.

하지만 그럼에도 불구하고 내가 잘못 이해했다는걸 인정하는 이유는
문자 그대로 받아들인 것도 사실 내 실수다.

내부 딕셔너리의 크기가 database 클래스의 size보다는 무조건작은 상황이어야 값을 insert할 수 있으니 말이다.

0개의 댓글