今さらPython3 (43) - 第6章復習課題

第6章の復習課題。

入門 Python 3

入門 Python 3

6.1
>>> class Thing():
...     pass
... 
>>> example = Thing()
>>> Thing
<class '__main__.Thing'>
>>> example
<__main__.Thing object at 0x102168c50>
>>> 

表示しようというのは中身を見ろという意味だと理解。exampleはインスタンス化しているのでロケーションが表示されるんだね。

6.2
>>> class Thing2():
...     letters = 'abc'
... 
>>> Things2.letters
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Things2' is not defined
>>> Things.letters
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Things' is not defined
>>> Thing2.letters
'abc'

print()した方が良かった?

6.3
>>> class Thing3():
...     def __init__(self):
...         self.letters = 'abc'
... 
>>> Thing3.letters
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Thing3' has no attribute 'letters'
>>> dummy = Thing3
>>> dummy.letters
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Thing3' has no attribute 'letters'
>>> dummy
<class '__main__.Thing3'>
>>> dummy = Thing3()
>>> dummy.letters
'abc'
>>> Thing3.letters
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Thing3' has no attribute 'letters'
>>> 

おっと、'xyz'じゃなくて'abc'と入れてしまったけど、間違えた場所も含めて書いておく。これを見る限り、クラスからオブジェクトを作ることは必要というのが回答と思われ。

>>> class Thing3():
...     def __init__(self, value):
...         self.letters = value
... 
>>> dummy = Thing3('xyz')
>>> dummy.letters
'xyz'
>>> Thing3.letters
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Thing3' has no attribute 'letters'
>>> 

結論は一緒だけど、教科書的な回答はこっちかな?

6.4
>>> class Element():
...     def __init__(self, name, symbol, number):
...         self.name = name
...         self.symbol = symbol
...         self.number = number
... 
>>> H = Element('Hydrogen', 'H', 1)
>>> H.name
'Hydrogen'
>>> H.symbol
'H'
>>> H.number
1
>>> 

こういうことで良いはず。

6.5
>>> h_dict = {'name': 'Hydrogen', 'symbol': 'H', 'number': 1}
>>> H2 = Element(h_dict['name'], h_dict['symbol'], h_dict['number'])
>>> hydrogen = H2
>>> hydrogen.name
'Hydrogen'
>>> hydrogen.symbol
'H'
>>> hydrogen.number
1
>>> 

もっとスマートな方法でやれってことかな?

>>> hydrogen2 = Element(**h_dict)
>>> hydrogen2.name
'Hydrogen'
>>> hydrogen2.symbol
'H'
>>> hydrogen2.number
1
>>> 
6.6

メソッドを作れと言うことは、クラスから作れって事かな?本の中では、関数を作ってたと思うんだけど。とりあえず両方試してみよう。関数を作るパターン。

>>> def dump(obj):
...     print('name: ', obj.name, '  symbol: ', obj.symbol, '  number: ', obj.number)
... 
>>> dump(hydrogen2)
name:  Hydrogen   symbol:  H   number:  1
>>> 

クラスからってことは、Elementクラスを拡張した方が良いのかな?ということで仕切り直し。

>>> class Element():
...     def __init__(self, name, symbol, number):
...         self.name = name
...         self.symbol = symbol
...         self.number = number
...     def dump(self):
...         print('Name: %s,  Symbol: %s,  Number:%s' % (self.name, self.symbol, self.number))
... 
>>> hydrogen = Element(**h_dict)
>>> hydrogen.dump()
Name: Hydrogen,  Symbol: H,  Number:1
>>> 
6.7
>>> print(hydrogen)
<__main__.Element object at 0x10216d320>

特殊メソッドに置き換えてね言っているので改造。

>>> class Element():
...     def __init__(self, name, symbol, number):
...         self.name = name
...         self.symbol = symbol
...         self.number = number
...     def __str__(self):
...         print('Name: %s,  Symbol: %s,  Number:%s' % (self.name, self.symbol, self.number))
... 
>>> hydrogen = Element(**h_dict)
>>> print(hydrogen)
Name: Hydrogen,  Symbol: H,  Number:1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __str__ returned non-string (type NoneType)

おっと。__str__に置き換えるということはprintじゃなくて、文字列をreturnしないといけないと想像。

>>> class Element():
...     def __init__(self, name, symbol, number):
...         self.name = name
...         self.symbol = symbol
...         self.number = number
...     def __str__(self):
...         return('Name: %s,  Symbol: %s,  Number:%s' % (self.name, self.symbol, self.number))
... 
>>> hydrogen = Element(**h_dict)
>>> print(hydrogen)
Name: Hydrogen,  Symbol: H,  Number:1
>>> 
6.8

Elementクラスをまた改造するのですね。

>>> class Element():
...     def __init__(self, name, symbol, number):
...         self.__name = name
...         self.__symbol = symbol
...         self.__number = number
...     @property
...     def name(self):
...         return self.__name
...     @property
...     def symbol(self):
...         return self.__symbol
...     @property
...     def number(self):
...         return self.__number
... 
>>> hydro = Element(**h_dict)
>>> hydro.name
'Hydrogen'
>>> hydro.symbol
'H'
>>> hydro.number
1
>>> hydro.name = 'Oxygen'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute
>>> 

もう少し分かりやすい名前にすれば良かったかもだけど、こういうことだよね。@name.setterなどがないので、ゲッターのみというのが現状での動き。

6.9
>>> class Bear():
...     def eats(self):
...         return 'berries'
... 
>>> class Rabbit():
...     def eats(self):
...         return 'clover'
... 
>>> class Octothorpe():
...     def eats(self):
...         return 'campers'
... 
>>> b = Bear()
>>> b.eats()
'berries'
>>> r = Rabbit()
>>> r.eats()
'clover'
>>> o = Octothorpe()
>>> o.eats()
'campers'
>>> 

え、これだけでいいの?

6.10
>>> class Laser():
...     def does(self):
...         return 'distintegrate'
... 
>>> class Claw():
...     def does(self):
...         return 'crush'
... 
>>> class SmatPhone():
...     def does(self):
...         return 'ring'
... 

Robotクラスを作りますと。

>>> class Robot():
...     def __init__(self):
...         self.laser = Laser()
...         self.claw = Claw()
...         self.smartphone = SmatPhone()
...     def does(self):
...         return '''The robot has following features:
... The laser does %s,
... The claw does %s,
... The smartphone does %s''' % (
... self.laser.does(), self.claw.does(), self.smartphone.does())
... 
>>> rob = Robot()
>>> rob.does()
'The robot has following features:\nThe laser does distintegrate,\nThe claw does crush,\nThe smartphone does ring'
>>> print(rob.does())
The robot has following features:
The laser does distintegrate,
The claw does crush,
The smartphone does ring
>>> 

改行位置に苦戦してエラーの屍累々だったことはここだけの秘密。

(つづく)