[들어가기 전에] 전역 변수 (Global Variable)과 이름 공간
result = 0
def add(num):
global result
result += num
add(3)
add(4)
result
7
def add_a(num):
result += num
add_a(5)
--------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/3474516729.py in <module> 2 result += num 3 ----> 4 add_a(5) /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/3474516729.py in add_a(num) 1 def add_a(num): ----> 2 result += num 3 4 add_a(5) UnboundLocalError: local variable 'result' referenced before assignment
def add_b(num):
result = 7
result += num
add_b(5)
result
7
result1 = 0
result2 = 0
def add1(num):
global result1
result1 += num
def add2(num):
global result2
result2 += num
add1(3)
add1(4)
add2(3)
add2(7)
result1
7
result2
10
class Calculator:
def __init__(self):
self.result = 0
def add(self, num):
self.result += num
cal1 = Calculator()
cal2 = Calculator()
cal1.add(3)
cal1.add(4)
cal2.add(3)
cal2.add(7)
class Car:
pass
class Dog:
pass
class Cat:
pass
car1 = Car()
car2 = Car()
car3 = Car()
my_dog = Dog()
yr_dog = Dog()
class Car:
accel = 3.0
mpg = 25
car1 = Car()
car2 = Car()
print('car1.accel = ', car1.accel)
print('car2.accel = ', car2.accel)
print('car1.mpg = ', car1.mpg)
print('car2.mpg = ', car2.mpg)
car1.accel = 3.0 car2.accel = 3.0 car1.mpg = 25 car2.mpg = 25
car1.accel = 3.0
car2.accel = 3.0
car1.mpg = 25
car2.mpg = 25
my_car = Car()
yr_car = Car()
my_car.accel = 5.0
print(my_car.accel)
print(yr_car.accel)
5.0 3.0
class Dog:
pass
my_dog = Dog() # Dog 인스턴스 생성
my_dog.name = 'Champ the Wonder Dog'
my_dog.breed = 'Great Dane'
my_dog.age = 5
print('Breed and age are {} and {}.'.format(my_dog.breed, my_dog.age))
Breed and age are Great Dane and 5.
yr_dog = Dog()
top_dog = Dog()
hot_dog = Dog()
hot_dog.name = 'Hotty Totty'
hot_dog.breed = 'Dachshund'
class 클래스 이름: #헤더(Header)
pass #몸체(Body)
class S1:
a = 1
print(S1.a)
print()
S1.b = 2 # 클래스 이름 공간에 새로운 이름의 생성
print(S1.b)
print()
print(dir(S1)) # S1에 포함된 이름들을 리스트로 반환
del S1.b # 이름 공간 S1에서 b삭제
print(dir(S1))
1 2 ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b'] ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a']
x = S1() # x는 S1의 인스턴스
print(x.a)
x.a = 10 # 인스턴스 x의 이름 공간에 이름 생성
print(x.a)
print(S1.a) # 클래스 이름 공간과 인스턴스 이름 공간은 다르다
1 10 1
y = S1() # S1 클래스의 또 다른 인스턴스 생성
y.a = 300 # 인스턴스 y의 이름 공간에 이름 생성
print(y.a)
print(x.a) # x 인스턴스 공간의 이름 a 확인
print(S1.a) # 클래스 이름 공간의 a 확인
300 10 1
class Simple:
pass
s1 = Simple()
s2 = Simple()
s1.stack = [] # 동적으로 인스턴스 이름 공간 안에 새로운 변수(이름) stack 생성
s1.stack.append(1) # 값 추가
s1.stack.append(2)
s1.stack.append(3)
print(s1.stack)
print(s1.stack.pop())
print(s1.stack.pop())
print()
print(s1.stack) # 최종 s1.stack값
print(s2.stack) # s2에는 stack을 정의한 적이 없다.
[1, 2, 3] 3 2 [1]
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/2042994929.py in <module> 9 print() 10 print(s1.stack) # 최종 s1.stack값 ---> 11 print(s2.stack) # s2에는 stack을 정의한 적이 없다. AttributeError: 'Simple' object has no attribute 'stack'
del s1.stack # s1에서 stack삭제
class Var:
c_mem = 100 # 클래스 멤버 정의
def f(self):
self.i_mem = 200 # 인스턴스 멤버 정의
def g(self):
print(self.i_mem)
print(self.c_mem)
print(Var.c_mem) # 클래스를 통하여 클래스 멤버 접근
100
v1 = Var() # 인스턴스 v1 생성
print(v1.c_mem) # 인스턴스를 통하여 클래스 멤버 접근
100
v1.f() # 인스턴스 멤버 i_mem이 생성됨
print(v1.i_mem) # 인스턴스 v1을 통하여 인스턴스 멤버 접근
200
v2 = Var() # 인스턴스 v2 생성
print(v2.c_mem)
print(v2.i_mem) # 인스턴스 v2에는 아직 f() 호출이 안되어서 i_mem 멤버 없음 ==> 생성자의 필요성
100
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/3624617570.py in <module> 1 v2 = Var() # 인스턴스 v2 생성 2 print(v2.c_mem) ----> 3 print(v2.i_mem) # 인스턴스 v2에는 아직 f() 호출이 안되어서 i_mem 멤버 없음 ==> 생성자의 필요성 AttributeError: 'Var' object has no attribute 'i_mem'
print(v1.c_mem) # 인스턴스 v1을 통해 클래스 멤버 참조
print(v2.c_mem) # 인스턴스 v2를 통해 클래스 멤버 참조
print()
v1.c_mem = 50 # 인스턴스 이름 공간에 c_mem생성
print(v1.c_mem) # 인스턴스 v1을 통해 인스턴스 멤버 참조
print(v2.c_mem) # 인스턴스 v2을 통해 클래스 멤버참조 (인스턴스 멤버가 없으므로, 클래스 멤버 참조)
print(Var.c_mem) # 클래스 멤버참조
100 100 50 100 100
class Dog:
def __init__(self, name, breed, age):
self.name = name
self.breed = breed
self.age = age
top_dog = Dog('Handsome Dan', 'Bulldog', 10)
#아래 3줄은 위 코드와 동일함
top_dog.name = 'Handsome Dan'
top_dog.breed = 'Bulldog'
top_dog.age = 10
good_dog = Dog('WonderBoy', 'Collie', 11)
__init__: 생성자 메소드
self
인자가 정의되어야 함__del__: 소멸자 메소드
self
인자가 정의되어야 함[참고] __ (연속된 두 개의 언더라인)의 의미: 예약된 (특수) 이름
mylife = Life()
로서 로컬 변수에 할당되는 인스턴스 mylife
가 생성되는 순간 __init__ 생성자 메소드 호출sleep(3)
에 의해 3초간 sleep 상태from time import ctime, sleep
class Life:
def __init__(self): # 생성자
self.birth = ctime() # 현재시간에 대한 문자열을 얻는다.
print('Birthday', self.birth) # 현재 시간 출력
def __del__(self): # 소멸자
print('Deathday', ctime()) # 소멸 시간 출력
def test():
mylife = Life()
print('Sleeping for 3 sec')
sleep(3) #3초간 sleep(block)상태에 있음 (즉, 3초간 CPU 점유 못함)
test()
Birthday Mon Nov 15 21:02:14 2021 Sleeping for 3 sec Deathday Mon Nov 15 21:02:17 2021
print
예약어나 str()
내장함수 호출에 대응되는 메소드class Integer:
def __init__(self, i):
self.i = i
def __str__(self):
return "self.i:" + str(self.i)
i = Integer(10)
print(i)
print(str(i))
self.i:10 self.i:10
# 문제가 발생하는 코드
class Marriage:
def __init__(self):
self.wife = Person('f')
self.husband = Person('m')
a_marriage = Marriage() # Person 클래스 초기화 누락
class Person:
def __init__(self, gender):
self.gender = gender
--------------------------------------------------------------------------- NameError Traceback (most recent call last) /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/461443531.py in <module> 5 self.husband = Person('m') 6 ----> 7 a_marriage = Marriage() # Person 클래스 초기화 누락 8 9 class Person: /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/461443531.py in __init__(self) 2 class Marriage: 3 def __init__(self): ----> 4 self.wife = Person('f') 5 self.husband = Person('m') 6 NameError: name 'Person' is not defined
# 문제가 발생하는 코드 수정
class Marriage:
def __init__(self):
self.wife = Person('f')
self.husband = Person('m')
class Person:
def __init__(self, gender):
self.gender = gender
a_marriage = Marriage() # 해당 라인을 끝으로 옮김
# 문제가 발생하는 코드 수정
class Marriage:
def __init__(self):
self.wife = Person('f')
self.husband = Person('m')
class Person:
def __init__(self, gender):
self.gender = gender
self.marriage = Marriage()
a_marriage = Marriage() # 해당 라인을 끝으로 옮김
--------------------------------------------------------------------------- RecursionError Traceback (most recent call last) /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/937282721.py in <module> 10 self.marriage = Marriage() 11 ---> 12 a_marriage = Marriage() # 해당 라인을 끝으로 옮김 /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/937282721.py in __init__(self) 2 class Marriage: 3 def __init__(self): ----> 4 self.wife = Person('f') 5 self.husband = Person('m') 6 /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/937282721.py in __init__(self, gender) 8 def __init__(self, gender): 9 self.gender = gender ---> 10 self.marriage = Marriage() 11 12 a_marriage = Marriage() # 해당 라인을 끝으로 옮김 ... last 2 frames repeated, from the frame below ... /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/937282721.py in __init__(self) 2 class Marriage: 3 def __init__(self): ----> 4 self.wife = Person('f') 5 self.husband = Person('m') 6 RecursionError: maximum recursion depth exceeded while calling a Python object
class Pretty:
def __init__(self, prefix):
self.prefix = prefix
def print_me(self, a, b, c):
print(self.prefix, a, sep='')
print(self.prefix, b, sep='')
print(self.prefix, c, sep='')
def print_class(): # 클래스 범위 메소드 (객체로 부터 호출 불가)
print("Preedy class")
printer = Pretty('-->')
printer.print_me(10, 20, 30) # 바운드 메소드 호출 (Bound Method Call)
-->10 -->20 -->30
Pretty.print_me(printer, 10, 20, 30) # 언바운드 메소드 호출 ( Unbound Method Call)
-->10 -->20 -->30
Pretty.print_class() # 클래스 범위 메소드 (객체로 부터 호출 불가)
Preedy class
printer.print_class()
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-41-a2ebfd9734cc> in <module> ----> 1 printer.print_class() TypeError: print_class() takes 0 positional arguments but 1 was given
- 위 제목에서 "전역 변수/메소드"는 삭제하고 공부하자!!!
class Odd:
def __init__(self):
self.x = 10
self.y = 20
self._u = 30 # 클래스 정의 내부에서만 사용하는 특수 변수라는 약속. 외부에서 직접 접근하는 것을 하지 말자는 약속. 접근은 허용됨
self.__z = 40 # Mangled Member --> 외부에서 접근 불가 ([주의] 메직 메소드 아님!!!)
def pr(self):
print('__z = ', self.__z)
def __pr(self):
print("!!!!!!!!!!!!!")
o = Odd()
o.x # 10
10
o.y # 20
20
o._u
30
o.__z # 에러!
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/1459712312.py in <module> ----> 1 o.__z # 에러! AttributeError: 'Odd' object has no attribute '__z'
o.pr()
__z = 40
o.__pr()
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) /var/folders/0z/7y5lq_xs3kv2s9p43vjt16bh0000gn/T/ipykernel_67644/614610455.py in <module> ----> 1 o.__pr() AttributeError: 'Odd' object has no attribute '__pr'
상속의 이유
부모 클래스 메소드 호출 방법
super(Subclass, self)
class Person:
def __init__(self, name, phone=None):
self.name = name
self.phone = phone
def __str__(self):
return '<Person {0} {1}>'.format(self.name, self.phone)
class Employee(Person): # 괄호 안에 쓰여진 클래스는 슈퍼클래스를 의미한다.
def __init__(self, name, phone, position, salary):
#Person.__init__(self, name, phone) # Person클래스의 생성자 호출 --> Unbound Method Call
super(Employee, self).__init__(name, phone) # --> Bound Method Call
self.position = position
self.salary = salary
p1 = Person('홍길동', 1498)
print(p1.name)
print(p1)
print()
m1 = Employee('손창희', 5564, '대리', 200)
m2 = Employee('김기동', 8546, '과장', 300)
print(m1.name, m1.position) # 슈퍼클래스와 서브클래스의 멤버를 하나씩 출력한다.
print(m1)
print(m2.name, m2.position)
print(m2)
홍길동 <Person 홍길동 1498> 손창희 대리 <Person 손창희 5564> 김기동 과장 <Person 김기동 8546>
l1 = [x for x in dir(p1) if not x.startswith("__")]
print(l1)
['name', 'phone']
l2 = [x for x in dir(m1) if not x.startswith("__")]
print(l2)
['name', 'phone', 'position', 'salary']
class Super:
def __init__(self):
print('Super init called')
class Sub(Super):
def __init__(self):
print('Sub init called')
s = Sub()
Sub init called
class Super:
def __init__(self):
print('Super init called')
class Sub(Super):
def __init__(self):
#Super.__init__(self) # Unbound 방식으로 슈퍼클래스의 생성자를 호출한다.
super(Sub, self).__init__() # 또는 왼쪽처럼 Bound 메소드 호출
print('Sub init called')
s = Sub()
Super init called Sub init called
class Super:
def __init__(self):
print('Super init called')
class Sub(Super):
pass
s = Sub()
Super init called
class Person:
def __init__(self, name, phone=None):
self.name = name
self.phone = phone
def __str__(self):
return '<Person %s %s>' % (self.name, self.phone)
class Employee(Person):
def __init__(self, name, phone, position, salary):
#Person.__init__(self, name, phone)
super(Employee, self).__init__(name, phone)
self.position = position
self.salary = salary
p1 = Person('gslee', 5284)
m1 = Employee('kslee', 5224, 'President', 500)
print(p1)
print(m1)
<Person gslee 5284> <Person kslee 5224>
class Employee(Person):
def __init__(self, name, phone, position, salary):
#Person.__init__(self, name, phone)
super(Employee, self).__init__(name, phone)
self.position = position
self.salary = salary
def __str__(self):
return '<Employee %s %s %s %s>' % (self.name, self.phone, self.position, self.salary)
p1 = Person('gslee', 5284)
m1 = Employee('kslee', 5224, 'President', 500)
print(p1)
print(m1)
<Person gslee 5284> <Employee kslee 5224 President 500>
class Employee(Person):
def __init__(self, name, phone, position, salary):
#Person.__init__(self, name, phone)
super(Employee, self).__init__(name, phone)
self.position = position
self.salary = salary
def __str__(self):
s = super().__str__() # 부모 객체의 메소드 호출 (bound)
s = s.replace("Person", "Employee")
return s + ' - <%s %s>' % (self.position, self.salary)
p1 = Person('gslee', 5284)
m1 = Employee('kslee', 5224, 'President', 500)
print(p1)
print(m1)
<Person gslee 5284> <Employee kslee 5224> - <President 500>
class Employee(Person):
def __init__(self, name, phone, position, salary):
#Person.__init__(self, name, phone)
super(Employee, self).__init__(name, phone)
self.position = position
self.salary = salary
def __str__(self):
s = Person.__str__(self) # 부모 객체의 메소드 호출 (unbound)
s = s.replace("Person", "Employee")
return s + ' - <%s %s>' % (self.position, self.salary)
p1 = Person('gslee', 5284)
m1 = Employee('kslee', 5224, 'President', 500)
print(p1)
print(m1)
<Person gslee 5284> <Employee kslee 5224> - <President 500>
상속 관계 내의 다른 클래스들의 인스턴스들이 같은 멤버 함수 호출에 대해 각각 다르게 반응하도록 하는 기능
다형성의 장점
파이썬에서 다형성의 장점
class Animal:
def cry(self):
print('...')
class Dog(Animal):
def cry(self):
print('멍멍')
class Duck(Animal):
def cry(self):
print('꽥꽥')
class Fish(Animal):
pass
for each in (Dog(), Duck(), Fish()):
each.cry()
멍멍 꽥꽥 ...
a = list()
print(a)
print(dir(a))
[] ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
class MyList(list):
def __sub__(self, other): # '-' 연산자에 대응되는 함수 정의
for x in other:
if x in self:
self.remove(x) # 각 항목을 하나씩 삭제한다.
return self
L = MyList([1, 2, 3, 'spam', 4, 5])
print(L)
print()
L = L - ['spam', 4]
print(L)
[1, 2, 3, 'spam', 4, 5] [1, 2, 3, 5]
class Stack(list): # 클래스 정의
def push(self, other):
self.append(other)
s = Stack() # 인스턴스 생성
s.push(4)
s.push(5)
print(s)
print()
s = Stack([1,2,3])
s.push(4)
s.push(5)
print(s)
print()
print(s.pop()) # 슈퍼 클래스인 리스트 클래스의 pop() 메소드 호출
print(s.pop())
print(s)
[4, 5] [1, 2, 3, 4, 5] 5 4 [1, 2, 3]
class Stack(list): # 클래스 정의
push = list.append
s = Stack() # 인스턴스 생성
s.push(4)
s.push(5)
print(s)
print()
s = Stack([1,2,3])
s.push(4)
s.push(5)
print(s)
print()
print(s.pop()) # 슈퍼 클래스인 리스트 클래스의 pop() 메소드 호출
print(s.pop())
print(s)
[4, 5] [1, 2, 3, 4, 5] 5 4 [1, 2, 3]
class Queue(list):
def enqueue(self, obj):
self.append(obj)
def dequeue(self):
return self.pop(0)
q = Queue()
q.enqueue(1) # 데이터 추가
q.enqueue(2)
print(q)
print(q.dequeue()) # 데이터 꺼내기
print(q.dequeue())
[1, 2] 1 2
class Queue(list):
enqueue = list.append
def dequeue(self):
return self.pop(0)
q = Queue()
q.enqueue(1) # 데이터 추가
q.enqueue(2)
print(q)
print(q.dequeue()) # 데이터 꺼내기
print(q.dequeue())
[1, 2] 1 2
a = dict()
print(a)
print(dir(a))
{} ['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
class MyDict(dict):
def keys(self):
K = list(dict.keys(self)) # 언바운드 메소드 호출 --> K = list(self.keys()) 라고 호출하면 무한 재귀 호출
K.sort()
return K
d = {'b':1, 'c':2, 'a':3}
print(d.keys())
print(list(d.keys()))
print()
d2 = MyDict({'b':1, 'c':2, 'a':3})
print(d2.keys())
dict_keys(['b', 'c', 'a']) ['b', 'c', 'a'] ['a', 'b', 'c']
class MyDict(dict):
def keys(self):
K = list(super().keys()) # 바운드 메소드 호출
K.sort()
return K
d = {'b':1, 'c':2, 'a':3}
print(d.keys())
print(list(d.keys()))
print()
d2 = MyDict({'b':1, 'c':2, 'a':3})
print(d2.keys())
dict_keys(['b', 'c', 'a']) ['b', 'c', 'a'] ['a', 'b', 'c']
print(int)
<class 'int'>
print(type(123) == int)
print(type(123) == type(0))
a = 12345678
print(type(a) == type(0))
True True True
print(isinstance(123, int))
True
class A:
pass
class B:
def f(self):
pass
class C(B):
pass
def check(obj):
print(obj, '=>', end=" ")
if isinstance(obj, A):
print('A', end="")
if isinstance(obj, B):
print('B', end="")
if isinstance(obj, C):
print('C', end="")
print()
a = A()
b = B()
c = C()
check(a)
check(b)
check(c)
<__main__.A object at 0x7fa2b8111710> => A <__main__.B object at 0x7fa2b03d34a8> => B <__main__.C object at 0x7fa2b8111080> => BC
class A:
pass
class B:
def f(self):
pass
class C(B):
pass
def check(class_obj):
print(class_obj, '=>', end=" ")
if issubclass(class_obj, A):
print('A', end="")
if issubclass(class_obj, B):
print('B', end="")
if issubclass(class_obj, C):
print('C', end="")
print()
check(A)
check(B)
check(C)
<class '__main__.A'> => A <class '__main__.B'> => B <class '__main__.C'> => BC
class Mammal:
def __init__(self, name, size):
self.name = name
self.size = size
def speak(self):
print("My name is", self.name)
def call_out(self):
self.speak()
self.speak()
self.speak()
class Pet:
pass
class Carnivore:
pass
class Dog(Mammal, Pet, Carnivore):
def __init__(self, name, size, breed):
Mammal.__init__(self, name, size) # 원하는 상위 클래스 생성자만 선택하여 호출
self.breed = breed
def speak(self):
print('ARF!')
dog = Dog("jack", 10, True)
dog.speak()
print(dog.size)
print("#" * 10)
dog.call_out()
ARF! 10 ########## ARF! ARF! ARF!
class Pet:
def __init__(self, nickname):
self.nickname = nickname
class Dog(Mammal, Pet, Carnivore):
def __init__(self, name, size, nickname, breed):
Mammal.__init__(self, name, size) # 원하는 상위 클래스 생성자만 선택하여 호출
Pet.__init__(self, nickname) # 원하는 상위 클래스 생성자만 선택하여 호출
self.breed = breed
def speak(self):
print('ARF!')
dog = Dog("jack", 10, "jackjack", True)
dog.speak()
print(dog.nickname)
print("#" * 10)
dog.call_out()
ARF! jackjack ########## ARF! ARF! ARF!
class X: pass
class Y: pass
class Z: pass
class A(X, Y): pass
class B(Y, Z): pass
class M(B, A, Z): pass
x = X()
y = Y()
z = Z()
a = A()
b = B()
m = M()
print(issubclass(A, X))
print(isinstance(a, X))
print()
print(issubclass(B, X))
print(isinstance(b, X))
print()
print(B.mro())
True True False False [<class '__main__.B'>, <class '__main__.Y'>, <class '__main__.Z'>, <class 'object'>]
print(issubclass(M, Z))
print(isinstance(m, Z))
print()
print(issubclass(M, X))
print(isinstance(m, X))
print()
print(issubclass(M, Y))
print(isinstance(m, Y))
True True True True True True
print(M.mro()) # method resolution order
[<class '__main__.M'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.X'>, <class '__main__.Y'>, <class '__main__.Z'>, <class 'object'>]
class Human:
def __init__(self, name):
self.name = name
class Coder:
def __init__(self, skills):
self.skills = skills
class Pythonista(Human, Coder):
def __init__(self, name, skills, dream):
Human.__init__(self, name)
Coder.__init__(self, skills)
self.dream = dream
obj = Pythonista("Alice", 3, 10)
print(obj.name)
print(obj.skills)
print(obj.dream)
Alice 3 10
class A:
def __init__(self):
print("Class A __init__()")
class B(A):
def __init__(self):
print("Class B __init__()")
A.__init__(self)
class C(A):
def __init__(self):
print("Class C __init__()")
A.__init__(self)
class D(B, C):
def __init__(self):
print("Class D __init__()")
B.__init__(self)
C.__init__(self)
d = D()
Class D __init__() Class B __init__() Class A __init__() Class C __init__() Class A __init__()
class A:
def __init__(self):
print("Class A __init__()")
class B(A):
def __init__(self):
print("Class B __init__()")
super().__init__()
class C(A):
def __init__(self):
print("Class C __init__()")
super().__init__()
class D(B, C):
def __init__(self):
print("Class D __init__()")
super().__init__()
d = D()
print(D.mro())
Class D __init__() Class B __init__() Class C __init__() Class A __init__() [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
class A:
def __init__(self):
print("Class A __init__()")
class B(A):
def __init__(self):
print("Class B __init__()")
super(B, self).__init__()
class C(A):
def __init__(self):
print("Class C __init__()")
super(C, self).__init__()
class D(B, C):
def __init__(self):
print("Class D __init__()")
super(D, self).__init__()
d = D()
print(D.mro())
Class D __init__() Class B __init__() Class C __init__() Class A __init__() [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
format(6, 'b')
'110'
class A:
pass
a = A()
a
<__main__.A at 0x7fa2a05846a0>
a.__str__()
'<__main__.A object at 0x7fa2a05846a0>'
a.__repr__()
'<__main__.A object at 0x7fa2a05846a0>'
a.__hash__()
8771028223082
class Point:
big_prime_1 = 1200556037
big_prime_2 = 2444555677
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
def __str__(self):
s = str(self.x) + ', '
s += str(self.y)
return s
def __repr__(self):
s = 'Point(' + str(self.x) + ', '
s += str(self.y) + ')'
return s
def __hash__(self):
n = self.x * big_prime_1
return (n + self.y) % big_prime_2
# def __bool__(self):
# return x and y
def __bool__(self):
if x == y:
return True
else:
return False
pt = Point(3, 4)
pt
Point(3, 4)
print(pt)
3, 4
bool(pt)
False
class Dog:
def __init__(self, n):
self.n = n
def __eq__(self, other):
''' == 를 구현하면 != 를 무료로 얻는다.'''
return self.n == other.n
def __lt__(self, other):
'' '< 를 구현하면 > 를 무료로 얻는다.'''
return self.n < other.n
def __le__(self, other):
''' <= 를 구현하면, >= 를 무료로 얻는다.'''
return self.n <= other.n
a = Dog(10)
b = Dog(100)
print(a == b, a != b)
False True
print(a < b, a > b)
True False
print(a <= b, a >= b)
True False
class Dog:
def __init__(self, d):
self.d = d
def __gt__(self, other):
'''
Greater than (>).
'''
print("__gt__() is called !!!!!!!!!!!")
if type(other) == Dog:
return self.d > other.d
else:
return self.d > other
def __lt__(self, other):
'''
Less than (<).
'''
print("__lt__() is called !!!!!!!!!!!")
if type(other) == Dog:
return self.d < other.d
else:
return self.d < other
# _ _repr_ _ 정의하는 것은 _ _str_ _도 갖게 되는 것이다.
def __repr__(self):
return "Dog(" + str(self.d) + ")"
d1 = Dog(1)
d2 = Dog(10)
d3 = 2
d1 < d2
__lt__() is called !!!!!!!!!!!
True
d1 < d3
__lt__() is called !!!!!!!!!!!
True
d2 < d1
__lt__() is called !!!!!!!!!!!
False
d3 < d1
__gt__() is called !!!!!!!!!!!
False
print(d1)
Dog(1)
d1, d5, d10 = Dog(1), Dog(5), Dog(10)
a_list = [50, d5, 100, d1, -20, d10, 3]
a_list.sort()
__lt__() is called !!!!!!!!!!! __gt__() is called !!!!!!!!!!! __lt__() is called !!!!!!!!!!! __lt__() is called !!!!!!!!!!! __gt__() is called !!!!!!!!!!! __gt__() is called !!!!!!!!!!! __lt__() is called !!!!!!!!!!! __lt__() is called !!!!!!!!!!! __lt__() is called !!!!!!!!!!! __gt__() is called !!!!!!!!!!! __gt__() is called !!!!!!!!!!! __gt__() is called !!!!!!!!!!!
a_list
[-20, Dog(1), 3, Dog(5), Dog(10), 50, 100]
import fractions
f = fractions.Fraction(1, 2)
print(f + 1) # Fraction._ _add_ _ 호출
print(2 + f) # Fraction._ _radd_ _ 호출
3/2 5/2
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
''' self+other를 포함한 포인트 반환.'''
newx = self.x + other.x
newy = self.y + other.y
return Point(newx, newy)
def __sub__(self, other):
''' 두 포인트의 거리 반환.'''
dx = self.x - other.x
dy = self.y - other.y
return (dx * dx + dy * dy) ** 0.5
def __mul__(self, n):
''' point 곱하기 스칼라 숫자 n.'''
newx = self.x * n
newy = self.y * n
return Point(newx, newy)
def __str__(self):
return "Point({0}, {1})".format(self.x, self.y)
pt1 = Point(10, 15)
pt2 = Point(0, 5)
x = pt1 + pt2
print(x)
Point(10, 20)
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
''' self+other를 포함한 포인트 반환.'''
newx = self.x + other.x
newy = self.y + other.y
return Point(newx, newy)
def __sub__(self, other):
''' 두 포인트의 거리 반환.'''
dx = self.x - other.x
dy = self.y - other.y
return (dx * dx + dy * dy) ** 0.5
def __mul__(self, n):
''' point 곱하기 스칼라 숫자 n.'''
newx = self.x * n
newy = self.y * n
return Point(newx, newy)
def __neg__(self):
newx = -self.x
newy = -self.y
return Point(newx, newy)
__invert__ = __neg__
def __trunc__(self):
newx = self.x.__trunc__()
newy = self.y.__trunc__()
return Point(newx, newy)
def __str__(self):
return "Point({0}, {1})".format(self.x, self.y)
pt1 = Point(3, 4)
pt2 = -pt1
pt3 = ~pt1
print(pt2.x, ', ', pt2.y, ', ', pt3.y, sep='')
-3, -4, -4
import math
pt1 = Point(5.5, -6.6)
pt2 = math.trunc(pt1)
print(pt2.x, ', ', pt2.y, sep='')
5, -6
# __add__ 구현이 없는 Dog 클래스 정의
class Dog():
def __init__(self, num):
self.num = num
# __radd__ 구현이 있는 Cat 클래스 정의
class Cat():
def __init__(self, num):
self.num = num
def __radd__(self, other):
return self.num + other.num
fido = Dog(4)
precious = Cat(5)
print(fido + precious) # 우측 객체에만 __radd__ 가 존재한다.
9
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
''' self+other를 포함한 포인트 반환.'''
newx = self.x + other.x
newy = self.y + other.y
return Point(newx, newy)
def __sub__(self, other):
''' 두 포인트의 거리 반환.'''
dx = self.x - other.x
dy = self.y - other.y
return (dx * dx + dy * dy) ** 0.5
def __mul__(self, n):
''' point 곱하기 스칼라 숫자 n.'''
newx = self.x * n
newy = self.y * n
return Point(newx, newy)
def __neg__(self):
newx = -self.x
newy = -self.y
return Point(newx, newy)
def __trunc__(self):
newx = self.x.__trunc__()
newy = self.y.__trunc__()
return Point(newx, newy)
def __rmul__(self, n):
''' 포인트와 스칼라 숫자 n과 곱셈한 결과를 반환한다 '''
newx = self.x * n
newy = self.y * n
return Point(newx, newy)
def __str__(self):
return "Point({0}, {1})".format(self.x, self.y)
pt1 = Point(1, 2)
pt2 = Point(5, 10)
pt3 = pt1 + pt2
print(pt3) # pt3 값 확인
Point(6, 12)
pt3 = pt1 * 5
print(pt3) # pt3 값 확인
Point(5, 10)
pt3 = 10 * pt1
print(pt3) # pt3 값 확인
Point(10, 20)
pt4 = -pt1
print(pt4)
Point(-1, -2)
# 역자주: 이해를 돕기 위해 MyClass 를 int 로 수정하였다
a = int(10)
b = a
a += 1
print(a, b) # a와 b가 여전히 같은 값을 가질까?
11 10
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __iadd__(self, other):
''' self+other를 포함한 포인트 반환.'''
newx = self.x + other.x
newy = self.y + other.y
return Point(newx, newy)
def __isub__(self, other):
''' 두 포인트의 거리 반환.'''
dx = self.x - other.x
dy = self.y - other.y
return (dx * dx + dy * dy) ** 0.5
def __imul__(self, n):
''' point 곱하기 스칼라 숫자 n.'''
newx = self.x * n
newy = self.y * n
return Point(newx, newy)
def __str__(self):
return "Point({0}, {1})".format(self.x, self.y)
pt1 = Point(1, 2)
pt2 = Point(3, 4)
pt1 += pt2
print(pt1)
Point(4, 6)
pt2 *= 5
print(pt2)
Point(15, 20)
class Point:
def __init__(self, x = 0, y = 0):
self.x = x
self.y = y
def __int__(self):
return int(self.x) + int(self.y)
def __float__(self):
return float(self.x) + float(self.y)
def __str__(self):
return "Point({0}, {1})".format(self.x, self.y)
p = Point(1, 2.5)
int(p)
3
float(p)
3.5
class Stack:
def __init__(self):
self.mylist = [] # Containment는 여기서 사용된다!
def append(self, v):
self.mylist.append(v)
def push(self, v):
self.mylist.append(v)
def pop(self):
return self.mylist.pop()
def peek(self):
return self.mylist[-1]
def __len__(self):
return len(self.mylist)
def __contains__(self, v):
return self.mylist.__contains__(v)
def __getitem__(self, k):
return self.mylist[k]
st = Stack()
st.push(10)
st.push(20)
st.push(30)
st.push(40)
print('Size of stack is:', len(st))
print('First elem is:', st[0])
print(10 in st)
print("#" * 10)
print('The top of the stack is:', st.peek())
print(st.pop())
print(st.pop())
print(st.pop())
print('Size of stack is:', len(st))
Size of stack is: 4 First elem is: 10 True ########## The top of the stack is: 40 40 30 20 Size of stack is: 1
print(st[0])
10
class Seq:
def __getitem__(self, n):
if n == 10:
raise IndexError()
return n
s = Seq()
s[0]
0
s[1]
1
s[9]
9
s[10]
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-34-34c622ab6870> in <module> ----> 1 s[10] <ipython-input-31-843cf36ab085> in __getitem__(self, n) 2 def __getitem__(self, n): 3 if n == 10: ----> 4 raise IndexError() 5 return n 6 IndexError:
class Seq:
def __init__(self, file):
self.file = open(file)
def __iter__(self):
return self
def __next__(self):
line = self.file.readline() # 한 라인을 읽는다.
if not line:
raise StopIteration # 읽을 수 없으면 예외 발생
return line # 읽은 라인을 리턴한다.
s = Seq('readme.txt') # s 인스턴스가 next() 메소드를 지니고 있으므로 s 인스턴스 자체가 반복자임
for line in s: # 우선 __iter__() 메소드를 호출하여 반복자를 얻고, 반복자에 대해서 for ~ in 구문에 의하여 __next__() 메소드가 호출됨
print(line)
print()
print(Seq('readme.txt'))
# list() 내장 함수가 객체를 인수로 받으면 해당 객체의 반복자를 얻어와 next()를 매번 호출하여 각 원소를 얻어온다.
print(list(Seq('readme.txt')))
# tuple() 내장 함수가 객체를 인수로 받으면 해당 객체의 반복자를 얻어와 next()를 매번 호출하여 각 원소를 얻어온다.
print(tuple(Seq('readme.txt')))
abc def ghi <__main__.Seq object at 0x7f831826c438> ['abc\n', 'def\n', 'ghi'] ('abc\n', 'def\n', 'ghi')
class Stack:
def __init__(self):
self.mylist = [] # Containment는 여기서 사용된다!
def append(self, v):
self.mylist.append(v)
def push(self, v):
self.mylist.append(v)
def pop(self):
return self.mylist.pop()
def peek(self):
return self.mylist[-1]
def __len__(self):
return len(self.mylist)
def __contains__(self, v):
return self.mylist.__contains__(v)
def __getitem__(self, k):
return self.mylist[k]
def __iter__(self):
self.current = 0
return self
def __next__(self):
if self.current < len(self):
self.current += 1
return self.mylist[self.current - 1]
else:
raise StopIteration
# 역자주: 테스트 코드
st = Stack()
st.push(10)
st.push(20)
st.push(30)
st.push(40)
for s in st:
print(s)
10 20 30 40
n = 5
if type(n) == int:
print('n is integer.')
n is integer.
n = 5
if isinstance(n, int):
print('n is an integer or derived from it.')
n is an integer or derived from it.
if isinstance(n, (int, float)):
print('n is numeric.')
n is numeric.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __mul__(self, other):
if type(other) == Point:
newx = self.x * other.x
newy = self.y * other.y
return Point(newx, newy)
elif type(other) == int or type(other) == float:
newx = self.x * other
newy = self.y * other
return Point(newx, newy)
else:
return NotImplemented
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __mul__(self, other):
if isinstance(other, Point):
newx = self.x * other.x
newy = self.y * other.y
return Point(newx, newy)
elif isinstance(other, (int, float)):
newx = self.x * other
newy = self.y * other
return Point(newx, newy)
else:
return NotImplemented
def __rmul__(self, other):
if isinstance(other, (int, float)):
newx = self.x * other
newy = self.y * other
return Point(newx, newy)
else:
return NotImplemented
pt1 = Point(2, 3)
pt2 = 5.5 * pt1
class Dog:
pass
d = Dog()
setattr(d, 'breed', 'Great Dane')
print(d.breed)
Great Dane
field = 'breed'
getattr(d, field)
'Great Dane'
메소드(Method) |
연산자(Operator) |
인스턴스 o에 대한 사용 예 |
__add__(self, B) |
+ (이항) |
o + B, o += B |
__sub__(self, B) |
- (이항) |
o - B, o -= B |
__mul__(self, B) |
* |
o * B, o *= B |
__truediv__(self, B) |
/ |
o / B, o /= B |
__rtruediv__(self, B) |
/ |
B / o |
__floordiv__(self, B) |
// |
o // B, o //= B |
__mod__(self, B) |
% |
o % B, o %= B |
__divmod__(self, B) |
divmod() |
divmod(o, B) |
__pow__(self, B) |
pow(), ** |
pow(o, B), o ** B |
__lshift__(self, B) |
<< |
o << B, o <<= B |
__rshift__(self, B) |
>> |
o >> B, o >>= B |
__and__(self, B) |
& |
o & B, o &= B |
__xor__(self, B) |
^ |
o ^ B, o ^= B |
__or__(self, B) |
| |
o | B, o |= B |
__neg__(self) |
- (단항) |
-A |
__abs__(self) |
abs() |
abs(o) |
__pos__(self) |
+ (단항) |
+o |
__invert__(self) |
~ |
~o |
class MyInteger:
def __init__(self, i):
self.i = i
def __str__(self):
return str(self.i)
def __add__(self, other):
return self.i + other
def __sub__(self, other):
return self.i - other
def __mul__(self, other):
return self.i * other
i = MyInteger(10)
print(i)
print(str(i))
print()
i = i + 10
print(i)
print()
i += 10
print(i)
print()
i += 15
print(i)
print()
i *= 10
print(i)
10 10 20 30 45 450
class MyInteger2:
def __init__(self, i):
self.i = i
def __str__(self):
return str(self.i)
def __add__(self, other):
return MyInteger2(self.i + other)
def __sub__(self, other):
return MyInteger2(self.i - other)
def __mul__(self, other):
return MyInteger2(self.i * other)
i = MyInteger2(10)
print(i)
print(str(i))
print()
i = i + 10
print(i)
print()
i += 10
print(i)
print()
i += 15
print(i)
print()
i *= 10
print(i)
10 10 20 30 45 450
class MyString:
def __init__(self, str):
self.str = str
def __truediv__(self, sep): # 나누기 연산자 /가 사용되었을 때 호출되는 함수
return self.str.split(sep) # 문자열 self.str을 sep를 기준으로 분리
m = MyString("abcd_abcd_abcd")
print(m / "_")
print(m / "_a")
print()
print(m.__truediv__("_"))
['abcd', 'abcd', 'abcd'] ['abcd', 'bcd', 'bcd'] ['abcd', 'abcd', 'abcd']
class MyString:
def __init__(self, str):
self.str = str
def __truediv__(self, sep):
return str.split(self.str, sep)
__rtruediv__ = __truediv__
m = MyString("abcd_abcd_abcd")
print(m / "_")
print(m / "_a")
print()
print("_" / m)
print("_a" / m)
['abcd', 'abcd', 'abcd'] ['abcd', 'bcd', 'bcd'] ['abcd', 'abcd', 'abcd'] ['abcd', 'bcd', 'bcd']
class MyString:
def __init__(self, str):
self.str = str
def __neg__(self):
t = list(self.str)
t.reverse()
return ''.join(t)
__invert__ = __neg__
m = MyString("abcdef")
print(-m)
print(~m)
fedcba fedcba
class MyString:
def __init__(self, str):
self.str = str
def __neg__(self):
t = list(self.str)
t.reverse()
return MyString(''.join(t))
def __str__(self):
return self.str
__invert__ = __neg__
m = MyString("abcdef")
m = -m
print(m)
m = ~m
print(m)
fedcba abcdef
class MyString:
def __init__(self, str):
self.str = str
def __floordiv__(self, sep):
return self.str.split(sep)[0]
def __mod__(self, sep):
return self.str.split(sep)[1]
def __divmod__(self, sep):
seperated_list = self.str.split(sep)
return seperated_list[0], seperated_list[-1]
m = MyString("aaaa_bbbb_cccc")
print(m // "_")
print(m % "_")
print(divmod(m, "_"))
print()
print(m.__floordiv__("_"))
print(m.__mod__("_"))
print(m.__divmod__("_"))
aaaa bbbb ('aaaa', 'cccc') aaaa bbbb ('aaaa', 'cccc')
메소드 | 연산자 | 비고 |
---|---|---|
__cmp__(self, other) | 아래 메소드가 부재한 상황에 호출되는 메소드 | python3.x 에서는 지원하지 않음 |
__lt__(self, other) | self < other | |
__le__(self, other) | self <= other | |
__eq__(self, other) | self == other | |
__ne__(self, other) | self != other | |
__gt__(self, other) | self > other | |
__ge__(self, other) | self >= other |
class MyInteger:
def __init__(self, i):
self.i = i
def __gt__(self, y):
return self.i > y
def __ge__(self, y):
return self.i >= y
def __lt__(self, y):
return self.i < y
def __le__(self, y):
return self.i <= y
def __eq__(self, y):
return self.i == y
def __ne__(self, y):
return self.i != y
c = MyInteger(10)
print(c > 1)
print(c >= 1)
print(c < 1)
print(c <= 1)
print()
print(c == 1)
print(c != 1)
True True False False False True
class MyInteger:
def __init__(self, i):
self.i = i
def __gt__(self, y):
if isinstance(y, MyInteger):
return self.i > y.i
elif isinstance(y, int):
return self.i > y
else:
return False
def __ge__(self, y):
if isinstance(y, MyInteger):
return self.i >= y.i
elif isinstance(y, int):
return self.i >= y
else:
return False
def __lt__(self, y):
if isinstance(y, MyInteger):
return self.i < y.i
elif isinstance(y, int):
return self.i < y
else:
return False
def __le__(self, y):
if isinstance(y, MyInteger):
return self.i <= y.i
elif isinstance(y, int):
return self.i <= y
else:
return False
def __eq__(self, y):
if isinstance(y, MyInteger):
return self.i == y.i
elif isinstance(y, int):
return self.i == y
else:
return False
def __ne__(self, y):
if isinstance(y, MyInteger):
return self.i != y.i
elif isinstance(y, int):
return self.i != y
else:
return False
c = MyInteger(10)
d = MyInteger(100)
e = 50
print(c > d)
print(c >= d)
print()
print(c > e)
print(c >= e)
print()
print(c < d)
print(c <= d)
print()
print(c < e)
print(c <= e)
print()
print(c == d)
print(c != d)
print()
print(c == e)
print(c != e)
False False False False True True True True False True False True
메소드 | 연산자 |
---|---|
__len__(self) | len() |
__contains__(self, item) | item in self |
__getItem__(self, key) | self[key] |
__setItem__(self, key, value) | self[key] = value |
__delItem__(self, key) | del self(key) |
class Square:
def __init__(self, end):
self.end = end
def __len__(self):
return self.end
def __getitem__(self, k):
if k < 0 or self.end <= k:
raise IndexError("Out of Index - " + str(k))
return k * k
s1 = Square(10)
print(len(s1)) # s1.__len__()
print()
print(s1[0]) #s1.__getitem__(0)
print(s1[1]) #s1.__getitem__(1)
print(s1[4]) #s1.__getitem__(4)
print(s1[9]) #s1.__getitem__(9)
print(s1[20])
10 0 1 16 81
--------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-158-a1a7e52a068a> in <module> 18 print(s1[4]) #s1.__getitem__(4) 19 print(s1[9]) #s1.__getitem__(9) ---> 20 print(s1[20]) <ipython-input-158-a1a7e52a068a> in __getitem__(self, k) 8 def __getitem__(self, k): 9 if k < 0 or self.end <= k: ---> 10 raise IndexError("Out of Index - " + str(k)) 11 return k * k 12 IndexError: Out of Index - 20
s1 = Square(10)
for x in s1:
print(x, end=" ")
0 1 4 9 16 25 36 49 64 81
s2 = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
for x in s2:
#print(x,)
print(x, end=" ")
0 1 4 9 16 25 36 49 64 81
print(list(s1))
print(tuple(s1))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] (0, 1, 4, 9, 16, 25, 36, 49, 64, 81)
class MyDict:
def __init__(self, d = None):
if d == None: d = {}
self.d = d
def __getitem__(self, k): #key
return self.d[k]
def __setitem__(self, k, v):
self.d[k] = v
def __len__(self):
return len(self.d)
m = MyDict() #__init__호출
m['day'] = 'light' #__setitem__호출
m['night'] = 'darkness' #__setitem__호출
print(m)
print(m['day']) #__getitem__호출
print(m['night']) #__getitem__호출
print(len(m)) #__len__호출
<__main__.MyDict object at 0x7fc818167828> light darkness 2
class MyDict:
def __init__(self, d=None):
if d == None: d = {}
self.d = d
def __getitem__(self, k):
return self.d[k]
def __setitem__(self, k, v):
self.d[k] = v
def __len__(self):
return len(self.d)
def keys(self):
return list(self.d.keys())
def values(self):
return list(self.d.values())
def items(self):
return list(self.d.items())
m = MyDict({'one':1, 'two':2, 'three':3})
print(m.keys())
print(m.values())
print(m.items())
['one', 'two', 'three'] [1, 2, 3] [('one', 1), ('two', 2), ('three', 3)]
class StringRepr:
def __repr__(self):
return 'repr called'
def __str__(self):
return 'str called'
s = StringRepr()
print(s)
print(str(s))
print(repr(s))
str called str called repr called
class StringRepr:
def __repr__(self):
return 'repr called'
s = StringRepr()
print(s)
print(str(s))
print(repr(s))
repr called repr called repr called
class StringRepr:
def __str__(self):
return 'str called'
s = StringRepr()
print(s)
print(str(s))
print(repr(s))
str called str called <__main__.StringRepr object at 0x7fc818173a58>
eval('10 + 20')
30
a = '10 + 20'
eval(a)
30
b = "print('abc')"
eval(b)
abc
class StringRepr:
def __init__(self, i = 10):
self.i = i
def __repr__(self):
return 'StringRepr(100)'
s = StringRepr()
q = eval(repr(s))
print(q.i)
100
class Accumulator:
def __init__(self):
self.sum = 0
def __call__(self, *args):
self.sum += sum(args)
return self.sum
acc = Accumulator()
print(acc(1,2,3,4,5))
print(acc(6))
print(acc(7,8,9))
print(acc.sum)
15 21 45 45
class A:
def __call__(self, v):
return v
class B:
def func(self, v):
return v
def check(func):
if callable(func):
print('callable')
else:
print('not callable')
a = A()
b = B()
check(a)
check(b)
print()
print(callable(a))
print(callable(b))
callable not callable True False