- 객체와 인스턴스 차이는 무엇이냐?
=> 객체(Object)는 소프트웨어 세계에 구현할 대상이고, 이를 구현하기 위한 설계도가 클래스(Class)이며, 이 설계도에 따라 소프트웨어 세계에 구현된 실체가 인스턴스(Instance)이다.
둘이 비슷한 개념이라고 생각하면 될듯하다. 다만 클래스는 객체와 인스턴스와는 다른 개념인것 정도는 알고 있어야한다.
- 객체지향이 무엇이냐?
=> 코드를 논리로 정리하기 위해서 논리적인 방법론(시각적 + 논리적인 코드 구조)
- class가 무엇이냐?
=> 아이템(클래스내 변수)들과 스킬(메서드)가 모아져 있는 / 도구와 동작들이 모아져 있는 직업, 역할
- 생성자가 무엇이냐?
=> 클래스가 실행될때 기존 태초마을에서 무조건 실행되는 코드
- 인스턴스(객체)가 무엇이냐?
=> 클래스로 찍어낸 것들
- 인스턴스 = 클래스이름(parameter) -> 클래스 옆에 들어가는 파라미터는 무엇이냐?
=> 생성자의 파라미터
- Field란
=> class에서 field란 클래스에 소속된 변수들을 멤버 변수 또는 필드라고 부른다.
- self가 무엇이냐?
=> 자기 자신, 인스턴스를 만들기 위한 인스턴스 자기 자신을 나타내는 것(사실 정의하는게 아직도 어렵다)
10/20일 보강
=> 인스턴스를 받는 파라미터로 모든 메서드는 처음에 인스턴스를 파라미터로 받는것 부터 시작이다. 이것이 없을경우에는 arguments를 하나 더 받는다고 에러가 뜬다.
네이스한 설명
-> 위 링크에서 f.func2()가 저장된 메모리와 class의 self가 지정한 메모리의 값이 동일한걸 확인할 수 있다.
즉 인스턴스 선언 -> 매서드 사용 -> 매서드의 self에 인스턴스가 들어감.
한줄정리: self는 매서드 썼을때 인스턴스 불러올 자리
-> 클래스 내부에 포함되어 있는 메서드나 변수
|속성 종류|
class 클래스명:
클래스 속성 = 값
def __init__(self, *args, *kwargs):
self.인스턴스 속성 = 값
...
<민싱식 정리>
-> 인스턴스 공통
-> 클래스 공통
-> 변하면 다른곳에서 클래스 변수를 사용하는곳 모두 변하게 됌
class Daeheeyun:
class_value = 0
def __init__(self):
self.instance_value = 0
def set_class_value(self):
Daeheeyun.class_value = 10
def set_instance_value(self):
self.class_value = 20
instance1 = Daeheeyun()
instance2 = Daeheeyun()
print("--클래스 속성 변경--")
instance1.set_class_value()
print(instance1.class_value, instance2.class_value)
print("--인스턴스 속성 변경--")
instance1.set_instance_value()
print(instance1.class_value, instance2.class_value)
print("--속성(Attribute) 출력--")
print(instance1.__dict__)
print(instance2.__dict__)
<민싱식 정리>
-> 인스턴스마다 값이 달라질수 있음
-> 다른 메모리에 변수/매서드 개념으로 저장
class Counter:
def __init__(self, value = 0):
self.value = value
def increment(self, delta = 1):
self.value += delta
def decrement(self, delta = 1):
self.value -= delta
static method, abstract method 깨닫고 정리
class User:
def __init__(self, email, password):
self.email = email
self.password = password
@classmethod
def fromTuple(cls, tup):
return cls(tup[0], tup[1])
@classmethod
def fromDictionary(cls, dic):
return cls(dic["email"], dic["password"])
사용법은 다음과 같다.
>>> user = User("user@test.com", "1234")
>>> user.email, user.password
('user@test.com', '1234')
>>> user = User.fromTuple(("user@test.com", "1234"))
>>> user.email, user.password
('user@test.com', '1234')
>>> user = User.fromDictionary({"email": "user@test.com", "password": "1234"})
>>> user.email, user.password
('user@test.com', '1234')
ex)
class StringUtils:
@staticmethod
def toCamelcase(text):
words = iter(text.split("_"))
return next(words) + "".join(i.title() for i in words)
@staticmethod
def toSnakecase(text):
letters = ["_" + i.lower() if i.isupper() else i for i in text]
return "".join(letters).lstrip("_")
사용법은 다음과 같다.(클래스이름.매서드(param))
>>> StringUtils.toCamelcase("last_modified_date")
'lastModifiedDate'
>>> StringUtils.toSnakecase("lastModifiedDate")
'last_modified_date'
<지리는 jeffery식 비유>
왜 쓰는가?
cf)
여기서 나올 수 있는 물음
from abc import *
class Human(metaclass=ABCMeta):
# 추상 메서드
@abstractmethod
def walk(self):
print('Human walk : 사람은 걸어요')
# 추상 메서드
@abstractmethod
def talk(self):
pass
# 일반 메서드
def sleep(self):
print('Human sleep : 사람은 자요')
# 자식 클래스 : 어른 클래스
class Adult(Human):
def walk(self):
print('Adult walk : 어른은 걷습니다.')
# 자식 클래스 : 아기 클래스
class Baby(Human):
# 추상 메서드
def walk(self):
print('Baby walk : 아기는 기어갑니다.')
def talk(self):
print('Baby talk : 아기는 옹알이를 합니다.')
# 객체 생성
# human = Human() # error
# adult = Adult() # error
baby = Baby()
# 재정의한 추상 메서드
baby.walk()
baby.talk()
# 부모 클래스 메서드
baby.sleep()
결과
- 왜 객체지향을 쓰는거냐?
-> 기존에 일일히 임무를 주기 어려움(노가다 코딩)
-> 직업들(class) 역할들을 category화해서 거기에 해당하는 도구들(클래스의 변수)들과 그것을 사용, 동작하는 스킬들을 모아 set화 시키자!
-> 직업, 역할에 따라 효율적으로 메뉴얼을 주어 일시키기 가능
class 칠판닦이:
성격 = "더러움" # 클래스 변수
def __init__(self, 교실: Classrom):
self.담당_교실 = 교실
self.지우개_깨끗함 = 0 # 멤버 변수/ 인스턴스변수
self.칠판_닦기()
def 칠판_닦기(self):
pass # 함수 안의 내용~~
칠판닦이_영수 = 칠판닦이(101호) # 인스턴스는 클래스로 찍어낸 녀석들
칠판닦이_영수.지우개_깨끗함 = 1
칠판닦이_영희 = 칠판닦이(102호)
칠판닦이_영수.지우개_깨끗함 == 칠판닦이_영희.지우개_깨끗함
칠판닦이.성격 = '깨끗함'
칠판닦이_철수 = 칠판닦이(111)
칠판닦이_철수.성격
칠판닦이_영수.칠판_닦기()
본 코드는 https://www.youtube.com/watch?v=vrhIxBWSJ04 영상 기준으로 공부했습니다.
-> self, cls가 없으면 자기 자신을 명시하지 못했기 때문에 그에 따른 속성들에 접근이 불가능함.
-> 인자 접근 가능성의 차이
what if?)
-> self.인스턴스변수명 은 인스턴스로 사용할 수 있으며 인스턴스로 활용할 매서드들에서 사용할 수 있는 변수임.
-> 매서드의 파라미터로 받는 변수 이름은 매서드 안에서의 로컬변수
test document들이 너무 많아 따로 파일을 만들어 클래스들에 다양한 매서드들로 만들었다.
class TEST_DOCUMENT_CODE_SPLITEER:
# Here is test documents with all language that splitter can split for test.
def __init__(
self,
PYTHON_TEST_DOCUMENT: Document = None
):
self.PYTHON_TEST_DOCUMENT = PYTHON_TEST_DOCUMENT
def PYTHON_TEST_DOCUMENT(self, PYTHON_TEST_DOCUMENT):
if PYTHON_TEST_DOCUMENT is None:
return Document(
page_content="""
def hello_world():
print("Hello, World!")
# Call the function
hello_world()
""",
metadata={
'source': 'test_source',
# Check whether the metadata_etc contains the multiple information from the TEST DOCUMENT metadatas or not.
'Data information': 'test for python code document',
'Data reference link': 'https://python.langchain.com/docs/modules/data_connection/document_transformers/text_splitters/code_splitter#python'
}
)
else:
return PYTHON_TEST_DOCUMENT
from test_document_for_code_splitter import Test_Document_Code_Splitter
# Here is test documents with all language that splitter can split for test.
# Which file do you want to test ?
# 왜 안됌???????? 똑같이 인스턴스 선언하고 매서드 불러왔는데
test_doc = Test_Document_Code_Splitter()
TEST_DOCUMENT = test_doc.PYTHON_TEST_DOCUMENT()
위에서 PYTHON_TEST_DOCUMENT
의 파라미터가 없다로 에러가 뜬다.
난 분명히 생성자에서 PYTHON_TEST_DOCUMENT: Document = None
으로 미리 default value를 설정해 주었고,
self.PYTHON_TEST_DOCUMENT = PYTHON_TEST_DOCUMENT
로 인스턴스 변수화 시켜주었다.
그리고 매서드에 def PYTHON_TEST_DOCUMENT(self, PYTHON_TEST_DOCUMENT):
로 생성자에서 선언한 인스턴스 변수를 매서드 파라미터로 input을 했다고 생각했다.
해결
=> 위의 매서드 def PYTHON_TEST_DOCUMENT(self, PYTHON_TEST_DOCUMENT):
의 PYTHON_TEST_DOCUMENT
는 매서드 내의 local variable이므로 생성자의 self.PYTHON_TEST_DOCUMENT
과는 이름은 같지만 아예 다른 녀석이다.
따라서 def PYTHON_TEST_DOCUMENT(self):
로 고치고,
if self.PYTHON_TEST_DOCUMENT is None:
로 생성자의 인스턴스 변수를 매서드에 이런식으로 불러오면 된다!
매서드를 불러올때마다 반복되는 split과 create document
토크나이저 이름을 선택하는것과 상관없이 항상 불필요한 다른 토크나이저도 파일 다운로드 받아서 생성자에서 인스턴스가 계속 만들어짐
항상 효율을 생각하자 불필요한 반복이 없는가>\?
참고문헌
https://engineer-mole.tistory.com/99
https://www.youtube.com/watch?v=vrhIxBWSJ04
https://076923.github.io/posts/Python-37/
https://www.daleseo.com/python-class-methods-vs-static-methods/