프리렉 - FREELEC
http://freelec.co.kr/book/catalogue_view.asp?UID=134
이강성저
class MyStr:
def __init__(self, s):
self.s = s
def __add__(self, s):
return MyStr(self.s + str(s))
def __sub__(self, o):
try:
k = self.s.index(o)
return MyStr(self.s[:k]+self.s[k+len(o):])
except ValueError:
return self
def __repr__(self):
return "MyStr('{}')".format(self.s)
a = MyStr("I like python and python")
a
a + " stuff"
a - "python"
class Square:
def __init__(self, n):
self.n = n
def __getitem__(self, k):
if 0 <= k <= self.n:
return k*k
raise IndexError("out of range {}".format(k))
s = Square(10)
s[2]
s[9]
list(s)
for ele in s:
print (ele, end=' ')
class Counter:
def __init__(self, n=0):
self.n = n
self.step = 1
def incr(self):
self.n += self.step
def __repr__(self):
return '{}'.format(self.n)
def __str__(self):
return '{}'.format(self.n)
def __call__(self):
self.incr()
return self.n
c = Counter()
c.incr()
c
c = Counter()
c()
c()
우선 __new__ 메서드를 이용한 싱글톤은 436-437페이지 참조
아무 문제없이 동작하는 싱글톤을 작성하기는 쉽지 않다. 다양한 싱글톤 구현 방법이 있지만 또한 각자의 문제를 안고 있다. 여기서는 __new__ 메서드를 이용한 싱글톤과 장식자를 이용한 싱글톤을 살펴보자.
# __new__ 메서드를 이용한 싱글톤 - 다중 상속인 경우
class Singleton(object):
_instance = None
def __new__(class_, *args, **kwargs):
if not isinstance(class_._instance, class_):
class_._instance = object.__new__(class_, *args, **kwargs)
return class_._instance
class BaseClass:
pass
class MyClass(Singleton, BaseClass):
pass
a = MyClass()
b = MyClass()
a is b
# __new__ 메서드를 이용한 싱글톤 - 순서가 바뀌고 __new__ 메서드가 중복되면 싱글톤 기능을 하지 못할 수 도 있다.
class Singleton(object):
_instance = None
def __new__(class_, *args, **kwargs):
if not isinstance(class_._instance, class_):
class_._instance = object.__new__(class_, *args, **kwargs)
return class_._instance
class BaseClass:
def __new__(class_, *args, **kwargs):
return object.__new__(class_, *args, **kwargs)
class MyClass(BaseClass, Singleton):
pass
a = MyClass()
b = MyClass()
a is b
def singleton(class_):
instances = {}
def getinstance(*args, **kwargs):
if class_ not in instances:
instances[class_] = class_(*args, **kwargs)
return instances[class_]
return getinstance
@singleton
class MyClass(BaseClass):
pass
m1 = MyClass()
m2 = MyClass()
m1 is m2
MyClass # 클래스가 아닌 함수
type(m2) # 반면에 인스턴스 객체의 자료형은 클래스이다. 뭔가 불일치 발생
type(m2) == MyClass # 따라서 이 것도 다를 수 밖에 없다.
o = type(m2)()
m1 is o # 이런..
class BNode:
def __init__(self, value=None, left=None, right=None):
self.value = value
self.left = left
self.right = right
def __repr__(self):
sleft = repr(self.left).replace('\n', '\n ')
sright = repr(self.right).replace('\n', '\n ')
return '%s (\n %s\n %s)' % (self.value, sleft, sright)
root = BNode('root')
root.left = BNode('left')
root.right = BNode('right')
root.left.left = BNode('left-left')
root.left.right = BNode('left-right')
print (root)
class BNode:
def __init__(self, value=None, left=None, right=None):
self.value = value
self.left = left
self.right = right
def __repr__(self):
indent = 4
sleft = repr(self.left).replace('\n', '\n'+' '*indent)
sright = repr(self.right).replace('\n', '\n'+' '*indent)
return '{0} (\n{1}{2}\n{1}{3})'.format(self.value, ' '*indent, sleft, sright)
root = BNode('root')
root.left = BNode('left')
root.right = BNode('right')
root.left.left = BNode('left-left')
root.left.right = BNode('left-right')
print (root)