class위주로 코드를 작성하는 것을 Object Oriented Programming(객체 지향 프로그래밍)이라고 하며,
그 내부에서 쓰일 객체들의 범위를 Scope라 한다.
이것 때문에 그 어떤 언어를 배우던지간에 맨날 객체~객체~~ 그랬던 것!
이 개념이 덜 잡혔을 땐 그놈의 객체지향형 객체 지향 그놈의 객체!!라고 생각했는데
지금은 이래서 객체지향^^.. 구래..^^ 이정도 느낌까지는 온 것 같다
각설하고 공부정리하자
scope : 범위
- 어떠한 객체(변수, 함수 등)가 유효한 범위
: 범위를 넘어가면 해당 객체는 사용될 수 없다
변수나 함수는 선언된 지점과 동일한 level의 지역, 그리고 더 안쪽의 지역들까지 범위가 유효하다!
이제 scope에 대한 더 상세한 개념들을 정리해보쟈
Local Scope : 지역변수
- 특정 범위 내에서만 유효
- 함수 내부에서 선언된 변수나 중첩 함수의 범위
Enclosing Scope
- 중첩함수가 있을 때 적용되는 범위
- 부모 함수에서 선언된 변수는 중첩함수 내에서도 유효
Global Scope : 전역변수
- 함수 밖에서 선언된 함수, 변수
- global scope를 가지는 변수, 함수들은 해당 파일에서 가장 바깥쪽에 선언되므로
해당 파일 내에서 선언된 지점 이후로는 늘 유효
Built-in Scope
- 파이썬 자체에 내장되어 있는, 파이썬이 제공하는 함수/속성
- 따로 선언하지 않아도 모든 파이썬 파일 내에서 유효
- list 및 자료구조들의 element 총 갯수를 리턴해주는 len( ) 함수도 built-in scope를 가진다
파이썬에서 변수, 함수의 정의를 찾을 때 scope들이 검색되는 순서
Local -> Enclosing -> Global -> Built-in
가장 좁은 유효범위 ~ 넓은 범위 순으로
사용되는 변수, 함수의 정의를 찾는다
** Shadowing 효과
클래스란 추상적인 개념으로, 없이도 코드를 구현할 수 있지만
코드의 구조를 더 효과적으로 구현할 수 있기 때문에 class를 사용한다
이처럼 class위주로 코드를 작성하는 것을 Object Oriented Programming(객체 지향 프로그래밍)이라고 한다!
class
- 추상적인, 큰 틀의 개념 같은 것!
- comedian이라는 큰 틀의 추상적인 개념(class)안에
각 개그맨들의 실체(instance)들이 구체화 되어있고,
이들을 객체(object)라고 한다.- 즉 instance == object인데,
class 내부에 class를 실체화(instantiate) 한 instance들을 object라 부른다고 생각하면 된다!class Car: hyundai = Car() bmw = Car()
- Class명은 대문자로 써줘야 하며 카멜 표기법으로 사용한다
: ScotchWhiskey
: SomeReallyLongClassName
Class의 attribute(속성)
- attribute(속성) : class에 정의되는 공통 요소들
- class내에서 정의하는 함수(function)는 function이라고 하지 않고 method라고 한다
class Car: def __init__(self, maker, model, horse_power): self.maker = maker self.model = model self.horse_power = horse_power
👉🏻 각 속성들을 class 내에서 정의하기 위해서
__init__
이라는 method를 사용한다.
- init과 같이
__
가 단어 앞 뒤로 있는 경우 special methods라고 하며,
이 중 init메 메서드는 class가 실체화 될 때 사용하는 함수!hyundai = Car("현대", "제네시스", 500)
- init 메서드는 명확하게 적어주지 않아도 class를 실체화할 때 자동으로 호출이 된다고 한다
짱신기
메서드 선언부를 보면, parameter를 self 포함 총 4개를 적어두었는데
왜 호출할 땐 3개만 넘겨준 걸까?
Self
- self : class의 실체(instance)인 객체(object)!
- class를 실체화 할 때 해당 객체(self)를 자동으로
__init__
함수에 넘겨준다
__init__
메서드는 클래스가 실체화 될 때 자동으로 호출된다__init__
의self
파라미터는 클래스가 실제화된 객체를 넘겨줘야 한다
(파이썬이 자동으로 넘겨줌)__init__
의 self 파라미터는 항상 정의되어있어야하며
맨 처음 파라미터로 정의해야 한다
class Car:
def __init__(self, maker, model, horse_power):
self.maker = maker
self.model = model
self.horse_power = horse_power
👆🏻👆🏻 요로케 parameter로 넘겨진 값들을 동일한 이름으로 self에 저장하는 데,
이는 객체에 넘겨받은 parameter를 저장하고 실체화해서
__init__
외에 다른 메서드에서 사용하려고 하는 것!
Class Method
class Car: def __init__(self, maker, model, horse_power): self.maker = maker self.model = model self.horse_power = horse_power - def honk(self): return f"{self.maker} 빠라바라빠라밤"
-
__init__
외에도 self 파라미터를 첫번째로 주고 honk 메서드를 선언하면,
dot Notation 을 사용해서 객체를 호출할 수 있다. 👉🏻 <객체>.<메서드>
hyundai = Car("현대", "제네시스", 500)
hyundai.honk()
> "현대 빠라바라빠라밤"
문제 풀이
- Database 라는 이름의 class를 구현해 주세요.
- Database 클래스 내부에 다음의 속성(attribute)들을 선언해주세요.
- name : database의 이름
- size : 저장할 수 있는 데이터의 max 사이즈. Size를 넘어서는 데이터를 저장할 수 없다.
- Database 클래스 내부에 다음의 메소드들을 구현해주세요.
- insert
- select
- update
- delete
각 메소드들에 대한 설명은 아래와 같습니다.
Insert
- insert 메소드는 self 외에 2개의 parameter를 받습니다.
: field와 value 입니다.- Field 는 저장하고자 하는 데이터의 필드명 이고 value는 값입니다.
- Field 와 value는 내부적으로 dictionary에 저장되어야 합니다.
- insert 메소드는 다음 처럼 호출 할 수 있습니다.
# 객체 이름이 db 라는 가정하에 db.insert("name", "정우성")
- insert 메소드는 특별한 리턴값은 없습니다.
- 만일 내부 dictionary의 총 사이즈가 database 클래스의 size 속성보다 크면 더이상 새로운 값들을 저장하지 말아야 합니다.
Select
- select 메소드는 self 외에 1개의 parameter를 받습니다.
: field 입니다.- Field 는 읽고자 하는 데이터의 필드명 입니다.
- 내부적으로 데이터를 저장하고 있는 dictionary에서 해당 field에 해당하는 키와 연결되어 있는 값을 리턴해주어야 합니다.
- 예를 들어, 이미 name이라는 필드명으로 "정우성" 이라는 값을 저장했다고 한다면:
# 객체 이름이 db 라는 가정하에 db.select("name") "정우성"
이 되어야 합니다.
- 만일 해당 필드값으로 저정되어 있는 값이 없다면 None 을 리턴해주세요.
Update
- Self 외에 2개의 parameter를 받습니다.
- field와 value 입니다.
- 이름 그대로 이미 저장되어 있는 값을 수정하는 메소드 입니다.
# 객체 이름이 db 라는 가정하에 db.update("name", "아이유")
- 만일 field값에 해당하는 데이터가 저장되어 있지 않으면 아무것도 하지 않습니다.
- 그리고 특별한 리턴 값은 없습니다.
Delete
- delete 메소드는 self 외에 1개의 parameter를 받습니다.
: field 입니다.- Field 는 지우고자 하는 데이터의 필드명 입니다.
# 객체 이름이 db 라는 가정하에 db.delete("name")
- 만일 field값에 해당하는 데이터가 저장되어 있지 않으면 아무것도 하지 않습니다.
- 그리고 특별한 리턴 값은 없습니다.
혼자서는 도저히 못짜겠어서 선배기수 velog를 찾아버렸다(그래도 insert method 이후로는 혼자 작성함ㅎㅎ)
내가 짠 코드
class Database: def __init__(self, name, size): self.name = name self.size = size self.db = {} # 내부 딕셔너리 - def insert(self, field, value): # my_dict = {"필드명": self.field, "값": self.value} if len(self.db) < self.size: self.db[field] = value - def select(self, field): if field in self.db: return self.db[field] else: return "None" - def update(self, field, value): if field in self.db: self.db[field] = value - def Delete(self, field): if field in self.db: del self.db[field]
처음엔 insert 메서드 문제만 보고, db라는 dictionary를 insert 메서드 내에 선언했었는데
알고보니 모든 메서드에서 사용해야 하는 dictionary였기 때문에
init 메서드에 선언해야 했다.
delete는 del 하고 dictionary명+[키] 이렇게 해준다는거 알쥐알쥐
하지만 해당 코드는 👆🏻 어마무시한 에러가 납니다
왜?
delete 메서드명을 대문자로 써놨기 때문^^
고쳤떠니 또 에러가 뜬다👇🏻👇🏻
왜?!
insert부분에서 리턴해주는 값이 그냥 None이어야하는데,
난 문자열로 리턴해주고 있기 때문!
고쳤는데 역시나 또 에러가 난다 👇🏻👇🏻👇🏻
왜,,? 😞😞😞
암만 생각해도 코드는 문제가 없는데,
이미 1 != 185라는 AssertionError가 났다는 건
어찌됐든 내 db라는 dictionary에서 1이라는 값을 찾았다는 것 아닌가
그럼 이건 채점하는 값이 문제인가 싶어서
~~이래도 되려나 싶긴 했지만 ~~채점하는값을 185에서 1로 바꾸어주었더니 통과했다
괜찮은거겠지..?