클래스에 대해 설명하기 전에 배운 꿀팁!
x = [1,2,3,4,5,6,7]
for i in x:
print(i)
리스트를 for문으로 하나하나 출력하게 된다면 안 그래도 무거운 Python이기에 속도가 느려요.
위의 코드와 결과는 같으면서 빠르게 하는 방법이 있어요.
x = [1,2,3,4,5,6,7]
# 속도가 훠어얼씬 빠름, 함수로 감싸서 하면 빨라짐
for _, i in enumerate(x): # _ 안 쓰면 ()에 감싸져서 인덱스가 같이 나옴
print(i)
위의 코드는 for문으로 그냥 돌린 것과 출력 결과는 같지만 속도면에서 빨라서 자주 사용한대요.
클래스
○ 변수와 함수를 묶어 놓은 개념
○ 클래스는 객체(데이터와 기능을 갖고 있는....)를 만들기 위한 설계도
○ 인스턴스(Instance) : 클래스를 메모리에 객체화 하는 것
class GrandMother: # 클래스 : 설계도
family = 'grandparents' # family(속성)
def print_self(self): # 메소드 : 클래스 내부 함수
print(self)
LEE = GrandMother() # 인스턴스화(객체 생성)
type(GrandMother), type(LEE)
print(f'속성호출 : {GrandMother.family}') # 속성 호출
print(f'메소드호출 : {GrandMother.print_self()}') # 메소드 호출
self = 인스턴스를 의미 (무조건 class 안에 self 있어야 함!)
인스턴스
○ self
GrandMother.print_self()를 실행시킨 결과 에러가 발생
에러 내용 : self가 존재하지 않습니다.
여기서 self는 객체(인스턴스)를 나타내서 객체 생성(아래의 경우 LEE)을 통해서만 사용이 가능해요.
(속성 호출(GrandMother.family)인 경우에는 self가 없으므로 사용이 가능해요.)
아래와 같이 하면 출력이 가능해요.
LEE = GrandMother()
LEE.print_self()
○ __init__
객체를 생성할 때, 생성자(__init__)라는 함수를 통해서 만들어져요.
만약 생성자를 선언하지 않으면 파이썬은 자동으로 만들어줘요.
객체를 생성할 때, 특별한 작업이 필요하다면 생성자를 작성해서 실행시킬 수 있어요.
● 인스턴스 속성과 클래스 속성의 차이
class Person:
name = "person name"
age = 18
def __init__(self, name):
self.name = name
# 클래스 속성값
print(f'Person.name : {Person.name} / Person.age : {Person.age}')
● 인스턴스에서 값 변경 (p_instant1)
# 인스턴스에서 값 변경(p_instant1)
p_instant1 = Person('인스턴트1')
p_instant1.age = 20
# 인스턴스 속성값
print(f'p_instant1.name : {p_instant1.name} / p_instant1.age : {p_instant1.age}')
● 인스턴스에서 값 변경2 (p_instant2)
# 인스턴스에서 값 변경(p_instant2)
# p_instant1 과 p_instant2는 다른 객체!
p_instant2 = Person('인스턴트222')
# 인스턴스 속성값
print(f'p_instant2.name : {p_instant2.name} / p_instant2.age : {p_instant2.age}')
인스턴스 1(p_instant1)과 인스턴스 2(p_instant2)는 서로 다른 객체
● 클래스 속성 값
# 클래스의 속성값
print(f'Person.name : {Person.name} / Person.age : {Person.age}')
# 인스턴스 생성을 통해 속성값을 여러번 변경했지만 클래스 속성값 변화 X
인스턴스를 여러 번 생성하여 속성을 변경 했지만 클래스의 속성값은 변화가 없다!!!
상속(inheritance)
부모 클래스의 내용(속성, 메소드)를 물려받는 자식 클래스가 가지게 되는 것
형태
class 부모클래스:
... 부모 코드(속성, 메소드) ...
class 자식클래스(부모클래스):
... 자식 코드(속성, 메소드) ... # 부모 클래스의 코드도 사용 가능!!!
예제로 알아볼게요.
우선 부모와 자식 클래스를 생성해볼게요.
부모 클래스 : GrandMother
자식 클래스 : father
# 부모 클래스
class GrandMother:
family = "Hello World"
name = "GrandMother"
def print_self(self):
print(self)
def print_HI():
print('HI!')
# 자식 클래스
class father(GrandMother):
name = 'father'
def __init__(self,name,age):
self.name = name
self.age = age
self.home = 'seoul'
father에는 print_HI 메서드가 없지만 GrandMother을 상속받아서 print_HI 메서드를 사용 가능해요.
father.print_HI()
child는 father을 상속받았어요. father이 GrandMother을 상속받았기에 child도 print_HI 메서드를 사용가능해요.
즉 여러 번 상속이 가능해요.
또 child.family를 하였더니 GrandMother에 있는 'Hello World'가 나와요.
class child(father):
name = 'child'
child.print_HI(), child.family
Override
부모로부터 받은 메서드 또는 속성을 수정하고 싶을 때 자식 클래스에서 재정의를 해요.
class PlayerCharacter:
def __init__(self,hp=100, exp=0):
self.hp = hp
self.exp = exp
def attack(self):
print('공격하기')
self.exp = self.exp + 2
def defend(self):
print('방어하기')
self.exp = self.exp + 1
Wizard는 PlayerCharacter을 상속받아서 defend를 수정해 주었어요. 이것이 메서드 오버라이딩이에요.
class Wizard(PlayerCharacter): #상속 받기
def __init__(self, mp):
super().__init__() # 부모클래스의 생성자를 실행하겠다.
self.mp = mp
def magic_skill(self):
print('마법 공격')
self.mp = self.mp - 2
# 메소드 오버라이딩
def defend(self):
print('마법사가 방어하기')
self.exp = self.exp + 3
Wizard 객체를 생성하여서 20을 하였더니 exp는 0이 나왔어요.
player = Wizard(20)
player.exp
defend 메서드를 실행하였더니 PlayerCharacter의 메서드가 아닌 오버라이딩된 '마법사가 방어하기'가 출력이 돼요.
player.defend()
player.exp
playerCharacter 객체를 생성한 origin_player는 defend 메서드를 실행하였더니 방어하기가 출력이 돼요.
origin_player = PlayerCharacter()
origin_player.defend()
origin_player.exp
접근 지정자(Access Specifiers)
○ Public
모든 멤버(속성, 메서드)는 default가 공용입니다. 모든 멤버는 객체 외부에서도 액세스를 할 수 있어요.
class Student:
schoolName = 'XYZ School' # class Attribute(클래스 내부 변수)
def __init__(self, name, age):
self.name = name # instance Attribute(인스턴스 내부 변수)
self.age = age # instance Attribute(인스턴스 내부 변수)
def display(self): # public method
print('This is public method')
std = Student('Steve', 25)
std.schoolName, std.name
값을 변경하게 되면? 변경될까요? 변경된답니다.
std.name = 'Dipa'
std.name
std.display()
○ Private
모든 프라이빗 멤버(속성, 메서드)는 객체 외부에서 엑세스가 불가합니다.
프라이빗 멤버들은 객체 내부에서만 호출이 가능해요.
class Student:
__schoolName = 'XYZ School' # private class Attribute(프라이빗 클래스 내부 변수)
def __init__(self, name, age):
self.name = name # instance Attribute(인스턴스 내부 변수)
self.age = age # instance Attribute(인스턴스 내부 변수)
def __display(self): # private method
print('This is public method')
std = Student("Bill", 25)
std.name
여기서 없는 __salary를 호출한다면?
std.__salary
그렇다면 존재하는 변수 schoolName, 메소드 __display()를 입력하면??
존재하지 않는 Attribute라고 나오네요. 바로 '__'(언더바 2개)로 Private 설정을 해주었기 때문이에요.
std.__schoolName
Decorators
Decorator 관련 글
2024.07.12 - [컴퓨터 공학/Networks] - SK networks AI Camp - Python_함수
SK networks AI Camp - Python_함수
함수(Function)하나의 특별한 목적의 작업을 수행하기 위해 독립적으로 설계된 코드의 집합1. 용어 ○ 입력 변수(함수에 입력하는 변수) : 파라미터 ○ 출력 변수(함수 결과) : 리턴 값 2. 왜 사
joowon582.tistory.com
○ @property
: 메서드를 속성으로 선언합니다.
○ @<properry-name>. setter : 속성에 값을 설정하는 속성에 대한 setter 메서드를 지정
○ @<property-name>. deleter : 속성을 삭제하는 속성으로 삭제방법을 지정
class Student:
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self, value):
self.__name = value
@name.deleter # Property-name, deleter decorator
def name(self):
print('Deleting...')
del self.__name
s = Student('Steve')
s.name
s.name = 'Bill'
s.name
del s.name
s.name
@classmethod
○ 클래스 메서드를 선언
○ 첫 번째 매개변수 : 클래스 속성에 액세스 하는 데 사용할 수 있는 cls여야(아래 코드 참고)함
○ 클래스 메서드 : 클래스 속성에만 액세스 가능, 인스턴스 속성에는 엑세스 불가
ClassName.MethodName() 및 객체를 사용해 호출 가능
○ 클래스의 객체를 반환 가능
class Student:
name = 'unknown' # class attribute
def __init__(self, name):
self.age = 20 # instance attribute
self.name = name # instance attribute
@classmethod
def tostring(cls):
print(f'StudentClass Attributes: name= {cls.name}')
Student.tostring(), Student.name
std = Student('test') # 객체를 생성하여 메소드 호출도 가능
std.tostring(), std.name
class Student:
name = 'unknown' # class attribute
def __init__(self, name):
self.age = 20 # instance attribute
self.name = name # instance attribute
@classmethod
def tostring(cls):
print(f'StudentClass Attributes: name= {cls.name}, age = {cls.age}')
Student.name
아래의 코드는 오류가 발생. Student 객체가 age가 없다고 하네요.
Student.tostring()
class Student:
def __init__(self, name, age):
self.age = age # instance attribute
self.name = name # instance attribute
@classmethod
def getobjcet(cls, name="Steve", age=25):
return cls(name, age)
std = Student('hi', 22)
std.name, std.age
다시 객체를 생성하면서 값을 지정하지 않으면 값이 초기값(Steve, 25)으로 변환
std = Student.getobjcet()
std.name, std.age
객체 생성할 때 값을 지정해 주면 값은 초기값이 X
std = Student.getobjcet('hi', 22)
std.name, std.age
@staticmethod
○ 클래스에서 정적 메서드를 선언
○ cls | self 매개변수를 가질 수 없음
○ 정적메서드 : 클래스 속성이나 인스턴스 속성에 액세스 불가
ClassName을 사용해 정적메서드 호출 가능
○ MethodName() 및 object.MethodName()도 사용
○ 클래스의 객체를 반환 가능
class Student:
name = 'unknown'
def __init__(self):
self.age = 20
@staticmethod
def tostring():
print('Student Class')
Student.tostring() # 그냥 메소드 호출
std = Student() # 객체 생성 후 메소드 호출
std.tostring()
Magic Methods
○ 메소드 명이 두 개의 언더바로 감싸져 있다.
○ 파이썬의 다양한 내장함수들이 클래스의 매직 메서드들을 호출해 결과를 만들어 냄
class MyDataset:
def __init__(self, data):
self.data = data
def __call__(self, a):
print(f'{a} 함수 호출 방법처럼 객체를 함수 호출하듯이 만들어주는 메소드')
return len(self.data)
def __getitem__(self, idx): # 인덱싱과 슬라이싱
return self.data[idx]
data = list(range(50, 100))
dt = MyDataset(data)
print(dt(1004))
print('-'*30)
print(dt[:5])
Initialization and Construction(초기화 및 구성)
Initialization and Construction | Description |
__new__(cls, other) | 객체의 인스턴스화에 의해 호출 |
__init__(self, other) | __new__ 메소드에 의해 호출 |
__del__(self) | 소멸자 방법 |
class Employee:
def __new__(cls):
print('__new__ magic method is called')
inst = object.__new__(cls)
return inst
def __init__(self):
print('__init__ magic method is called')
self.name = 'Saka'
emp = Employee()
class Employee:
def __init__(self, salary):
self.salary = salary
def __round__(self, n):
return round(self.salary*10, n)
emp = Employee(33.33333)
round(emp, 2)
Unary operators and functions(단항 연산자 및 호출)
Unary operators and functions | Description |
__pos__(self) | 단항 긍정문 호출 e.g. +someobject |
__neg__(self) | 단한 부정문 호출 e.g. -someobject |
__abs__(self) | 내장된 abs() 함수에 의해 호출 |
__invert__(self) | ~ 연산자를 사용하여 반전 호출 |
__round__(self, n) | 내장된 round() 함수에 의해 호출 |
__floor__(self) | 내장된 math.floor() 함수에 의해 호출 |
__cell__(self) | 내장된 math.cell() 함수에 의해 호출 |
__trunc__(self) | 내장된 math.trunc() 함수에 의해 호출 |
* round(a, b) : a를 b이하 자릿수에서 반올림 e.g. round(3.141592, 2) ==> 3.14
* floor(a) : a의 내림값 반환
* cell(a) : a의 올림값 반환
* trunc(a) : 해당 값에서 0에 가까운 정수 선택(= 버림) e.g. math.trunc(1.5) ==> 1
* floor()와 trunc()의 차이
● 양수에서는 비슷하게 동작하지만 음수에서 다름.
floor() 함수 : 음수에 대해서는 내림연산
trunc() 함수 : 단순히 소수점 아래를 잘라내기 때문에 음수에 대해서는 소수점 이하를 올림 하는 효과
class Employee:
def __init__(self, salary):
self.salary = salary
def __str__(self):
return f'salary : {str(self.salary)}'
emp = Employee(33.3333)
str(emp)
String
String Magic Methods | Description |
__str__(self) | 내장된 str() 메소드에 의해 호출되어 유형의 문자열 표현을 반환하고자 할때 |
__repr__(self) | 내장된 repr()메소드에 의해 호출되어 기계가 읽을 수 있는 유형의 표현을 반환하고자 할때 |
__unicode__(self) | 내장된 unicode() 메소드에 의해 호출되어 특정 유형의 유니코드 문자열 반환하고자 할때 |
__format__(self, formatstr) | 내장된 string.format() 메소드에 의해 호출되어 새로운 스타일의 문자열 반환하고자 할때 |
__hash__(self) | 내장된 hash() 메소드에 의해 호출되어 정수를 반환하고자 할때 |
__nonzero__(self) | 내장된 bool() 메소드에 의해 호출되어 True | False를 반환하고자 할 때 |
__dir__(self) | 클래스의 속성목록을 반환하기 위해 내장된 dir() 메소드에 의해 호출됨 |
__sizeof__(self) | 내장된 sys.getsizeof() 메소드에 의해 호출되어 객체의 크기를 반환하고자 할 때 |
표준 라이브러리 함수의 경우 다음에 따로 포스팅하겠습니다!
'Networks > Python' 카테고리의 다른 글
SK networks AI Camp - Python(Class_보충) (0) | 2024.07.17 |
---|---|
SK networks AI Camp - Python 표준 라이브러리(함수) (2) | 2024.07.16 |
SK networks AI Camp - Python 내장 함수 (0) | 2024.07.15 |
SK networks AI Camp - Python(함수) (2) | 2024.07.15 |
SK networks AI Camp - 오류(Exception)와 예외처리 (6) | 2024.07.14 |