基本構文②
実験結果を整理しました
継承とフィールドとコンストラクタ
class Base1: def __init__(self):# コンストラクタ print("Base1.__init()__") self.__private_field = 0 # privateフィールド(__始まり) self._protected_field = 0 # protectedフィールド(_始まり)→ウソ。protectedはないらしい self.public_field = 0 # publicフィールド def func(self): print(self._protected_field) print(self.public_field) def func2(self): # print(self.__private_field) print(self._protected_field) print(self.public_field) b = Base1() b.__private_field = 10 b._protected_field = 11 b.public_field = 12 b.func2() # 0, 11, 12(privateは書き換えられていない) class Base2: def __init__(self): print("Base2.__init()__") def __init__(self, hoge): print("Base2.__init(hoge)__") self.__hoge = hoge # クラス継承 class Deriver(Base1): def __init__(self): self.__private_field = 10 self._protected_field = 2 self.public_field = 3 def func3(self): print(self.__private_field) print(self._protected_field) print(self.public_field) deriver = Deriver() deriver.__private_field = 20 deriver._protected_field = 21 deriver.public_field = 22 deriver.func() # 21, 22 deriver.func2() # AttributeError: 'Deriver' object has no attribute '_Base1__private_field'. Did you mean: '_Deriver__private_field'? deriver.func3() # 10, 21, 22 # クラス継承(多重継承) class Deriver2(Base1, Base2): def __init__(self): super().__init__() # Base1.__init()__ super(Deriver2, self).__init__() # Base1.__init()__ super(Base2, self).__init__() # do nothing # super(Deriver2, self).__init__("hoge") # TypeError: Base1.__init__() takes 1 positional argument but 2 were given # super(Base2, self).__init__("hoge") # TypeError: object.__init__() takes exactly one argument (the instance to initialize) deriver2 = Deriver2() Deriver2.mro() # [<class '__main__.Deriver2'>, <class '__main__.Base1'>, <class '__main__.Base2'>, <class 'object'>] # 多重継承の場合先に指定したクラスのコンストラクタしか呼べない?
デコンストラクト
# デコンストラクト l = [1, 2, 3] a1, a2, a3 = l print(a1) # 1 print(a2) # 2 print(a3) # 3
コールバックとラムダ式
# Callback from typing import Callable, TypeVar TArgs = TypeVar("TArgs") # Generic型宣言 TResult = TypeVar("TResult") def callback(arg1, arg2, cb : Callable[[TArgs, TArgs], TResult]):# Callable型を使用。 return cb(arg1, arg2) # Callback処理(ラムダ式) action = lambda x , y : x * y result = callback(4, 5, action) result # 20
リスト内包表記
# リスト内包表記(新しいリストを作る) l = [1, 2, 3, 4, 5] [e * 2 for e in l] # [2, 4, 6, 8, 10] [e * 2 for e in l if e % 2 == 0] # [4, 8]
yield と generator
# yield / generator l = [1, 2, 3, 4, 5] def create_generator(ite): for e in ite: yield e g = create_generator(l)# generator # nextのたびにyieldに処理が来てループ再開 print(next(g)) # 1 print(next(g)) # 2 print(next(g)) # 3 print(next(g)) # 4 print(next(g)) # 5 print(next(g)) # StopIterationException # yield / generator応用編(遅延実行コールバック) from typing import Iterable,TypeVar T = TypeVar("T") l = [1, 2, 3, 4, 5] def condition_iter(ite:Iterable[T], condition:Callable[[T], bool]): for e in ite: if condition(e): yield e for e in condition_iter(l, lambda x : x % 2 == 0): print(e) # 2, 4
ライブラリの再ロード
インタプリタでモジュール分割したファイルを動かすために、再ロードが必要になる。
import importlib importlib.reload("lib name")