## 2014年5月2日金曜日

### Python - Classes and OOP(Advanced Class Topics)

Learning Python (Mark Lutz (著)、Oreilly & Associates Inc)のPART Ⅵ.(Classes and OOP)、CHAPTER 32(Advanced Class Topics)、Test Your Knowledge: Quiz.1.~ 7.を解いてみる。

その他参考書籍

1. コード(BBEdit)

sample.py

```#!/usr/bin/env python3
#-*- coding: utf-8 -*-

# extend list class
# embedding
class MyList1:
def __init__(self, data=[]):
self.data = data
if isinstance(other, MyList1):
other = other.data
return MyList1(self.data + other)
return MyList1(other + self.data)
def __str__(self):
return "MyList1({0})".format(self.data)

# subclassing
class MyList2(list): pass

if __name__ == '__main__':
o0 = MyList1()
o1 = MyList1(['python'])
o2 = MyList1([1, 2])
myLists1 = [o0, o1, o2]
l0 = []
l1 = ['python']
l2 = [1, 2]
lists = [l0, l1, l2]
objects1 = lists + myLists1
for x in myLists1:
print('MyList1 + MyList1')
for y in myLists1:
print('{0} + {1} = {2}'.format(x, y, x + y))
print('MyList1 + list')
for y in lists:
print('{0} + {1} = {2}'.format(x, y, x + y))
print('list + MyList1')
for y in lists:
print('{0} + {1} = {2}'.format(y, x, y + x))

o3 = MyList2()
o4 = MyList2(['python'])
o5 = MyList2([1, 2])
myLists2 = [o3, o4, o5]
for x in myLists2:
print('MyList2 + MyList2')
for y in myLists2:
print('{0} + {1} = {2}'.format(x, y, x + y))
print('MyList2 + list')
for y in lists:
print('{0} + {1} = {2}'.format(x, y, x + y))
print('list + MyList2')
for y in lists:
print('{0} + {1} = {2}'.format(y, x, y + x))
```

入出力結果(Terminal)

```\$ ./sample.py
MyList1 + MyList1
__add__ :MyList1([]) + MyList1([]) = MyList1([])
__add__ :MyList1([]) + MyList1(['python']) = MyList1(['python'])
__add__ :MyList1([]) + MyList1([1, 2]) = MyList1([1, 2])
MyList1 + list
__add__ :MyList1([]) + [] = MyList1([])
__add__ :MyList1([]) + ['python'] = MyList1(['python'])
__add__ :MyList1([]) + [1, 2] = MyList1([1, 2])
list + MyList1
__radd__:[1, 2] + MyList1([]) = MyList1([1, 2])
MyList1 + MyList1
__add__ :MyList1(['python']) + MyList1([]) = MyList1(['python'])
__add__ :MyList1(['python']) + MyList1(['python']) = MyList1(['python', 'python'])
__add__ :MyList1(['python']) + MyList1([1, 2]) = MyList1(['python', 1, 2])
MyList1 + list
__add__ :MyList1(['python']) + [] = MyList1(['python'])
__add__ :MyList1(['python']) + ['python'] = MyList1(['python', 'python'])
__add__ :MyList1(['python']) + [1, 2] = MyList1(['python', 1, 2])
list + MyList1
__radd__:['python'] + MyList1(['python']) = MyList1(['python', 'python'])
__radd__:[1, 2] + MyList1(['python']) = MyList1([1, 2, 'python'])
MyList1 + MyList1
__add__ :MyList1([1, 2]) + MyList1([]) = MyList1([1, 2])
__add__ :MyList1([1, 2]) + MyList1(['python']) = MyList1([1, 2, 'python'])
__add__ :MyList1([1, 2]) + MyList1([1, 2]) = MyList1([1, 2, 1, 2])
MyList1 + list
__add__ :MyList1([1, 2]) + [] = MyList1([1, 2])
__add__ :MyList1([1, 2]) + ['python'] = MyList1([1, 2, 'python'])
__add__ :MyList1([1, 2]) + [1, 2] = MyList1([1, 2, 1, 2])
list + MyList1
__radd__:[] + MyList1([1, 2]) = MyList1([1, 2])
__radd__:['python'] + MyList1([1, 2]) = MyList1(['python', 1, 2])
__radd__:[1, 2] + MyList1([1, 2]) = MyList1([1, 2, 1, 2])
MyList2 + MyList2
[] + [] = []
[] + ['python'] = ['python']
[] + [1, 2] = [1, 2]
MyList2 + list
[] + [] = []
[] + ['python'] = ['python']
[] + [1, 2] = [1, 2]
list + MyList2
[] + [] = []
['python'] + [] = ['python']
[1, 2] + [] = [1, 2]
MyList2 + MyList2
['python'] + [] = ['python']
['python'] + ['python'] = ['python', 'python']
['python'] + [1, 2] = ['python', 1, 2]
MyList2 + list
['python'] + [] = ['python']
['python'] + ['python'] = ['python', 'python']
['python'] + [1, 2] = ['python', 1, 2]
list + MyList2
[] + ['python'] = ['python']
['python'] + ['python'] = ['python', 'python']
[1, 2] + ['python'] = [1, 2, 'python']
MyList2 + MyList2
[1, 2] + [] = [1, 2]
[1, 2] + ['python'] = [1, 2, 'python']
[1, 2] + [1, 2] = [1, 2, 1, 2]
MyList2 + list
[1, 2] + [] = [1, 2]
[1, 2] + ['python'] = [1, 2, 'python']
[1, 2] + [1, 2] = [1, 2, 1, 2]
list + MyList2
[] + [1, 2] = [1, 2]
['python'] + [1, 2] = ['python', 1, 2]
[1, 2] + [1, 2] = [1, 2, 1, 2]
\$
```
2. staticmethodの定義するとき等にdecoratorを使う。
3. python3.xでは最初からすべてnew-style class(すべてのクラスがobjectを継承している)
4. 3.の通り、new-style classはobjectから派生している。
5. normal methodはインスタンスと、static methodはクラスと結びついている。

コード(BBEdit)

sample.py

```#!/usr/bin/env python3
#-*- coding: utf-8 -*-

class A:
count = 0
# static method
def counter():
print(A.count)
# normal method
def __init__(self):
A.count += 1
def meth(self):
print('Hello, world!')

if __name__ == '__main__':
a = A()
A.counter()
try:
a.counter()
except Exception as err:
print(type(err), err, err.args)
try:
A.meth()
except Exception as err:
print(type(err), err, err.args)
A.meth(a)
a.meth()
b = A()
A.counter()
```

入出力結果(Terminal)

```\$ ./sample.py
1
<class 'TypeError'> counter() takes 0 positional arguments but 1 was given ('counter() takes 0 positional arguments but 1 was given',)
<class 'TypeError'> meth() missing 1 required positional argument: 'self' ("meth() missing 1 required positional argument: 'self'",)
Hello, world!
Hello, world!
2
\$
```
6. yes.
7. pass