クラス変数インスタンス変数
class MyClassA: counter=0 #クラス変数(どのインスタンスにも共通の変数=おまけ) def __init__(self): #引数なし self.name = "" # インスタンス変数 self.counter+=1 MyClassA.counter+=1 print('ID:MyClassA.counter',id(MyClassA.counter)) #505986456 #0 a1 = MyClassA() print('MyClassA.counter',MyClassA.counter) print('ID:MyClassA.counter',id(MyClassA.counter)) #505986472 #1 a1.name = "Tanaka" #インスタンス化後代入 a2 = MyClassA() print('MyClassA.counter',MyClassA.counter) print('ID:MyClassA.counter',id(MyClassA.counter)) #505986488 #2 print (a1.name) print (a2.name ) #------------------------------------------------- a1.name='変態' a2.name='秋葉原' print (a1.name) print (a2.name) #print(counter) エラー print('a1.counter',a1.counter) #1(インスタンスが作られた合計回数) print('MyClassA.counter',MyClassA.counter) print('a2.counter',a2.counter) #2(インスタンスが作られた合計回数) #print(b1.counter) エラー'MyClassB' object has no attribute 'counter' print('MyClassA.counter',MyClassA.counter) #2 #print(MyClassA.name) エラー'MyClassA' has no attribute 'name' #print(MyClassB.name) エラー'MyClassB' has no attribute 'name' print('ID:a1.counter',id(a1.counter)) #505986472 #1 print('ID:a2.counter',id(a2.counter)) #505986488 #2 print('ID:MyClassA.counter',id(MyClassA.counter)) #505986488 #2 #--------------------------------------------------------------------- class MyClassB(): def __init__(self,arg): self.name = arg b1 = MyClassB("Yamamoto") #引数有りのインスタンス化 b2 = MyClassB("Saitou") print (b1.name) #Yamamoto print (b2.name) #Saitou b1.name='フィギア' b2.name='中年少年' print (b1.name) #フィギア print (b2.name) #中年少年
class MyClassA: counter=0 #クラス変数(どのインスタンスにも共通の変数=おまけ) def __init__(self): #引数なし self.name = "" # インスタンス変数 MyClassA.counter+=1 print('ID:MyClassA.counter',id(MyClassA.counter)) #505986456 #0 a1 = MyClassA() print('MyClassA.counter',MyClassA.counter) #1 print('ID:MyClassA.counter',id(MyClassA.counter)) #505986472 #1 a1.name = "Tanaka" #インスタンス化後代入 a2 = MyClassA() print('MyClassA.counter',MyClassA.counter) #2 print('ID:MyClassA.counter',id(MyClassA.counter)) #505986488 #2 print (a1.name) print (a2.name ) #------------------------------------------------- a1.name='変態' a2.name='秋葉原' print (a1.name) print (a2.name) #print(counter) エラー print('a1.counter',a1.counter) #2(インスタンスが作られた合計回数) print('MyClassA.counter',MyClassA.counter) print('a2.counter',a2.counter) #2(インスタンスが作られた合計回数) #print(b1.counter) エラー'MyClassB' object has no attribute 'counter' print('MyClassA.counter',MyClassA.counter) #2 #print(MyClassA.name) エラー'MyClassA' has no attribute 'name' #print(MyClassB.name) エラー'MyClassB' has no attribute 'name' print('ID:a1.counter',id(a1.counter)) #505986488 #2 print('ID:a2.counter',id(a2.counter)) #505986488 #2 print('ID:MyClassA.counter',id(MyClassA.counter)) #505986488 #2 #--------------------------------------------------------------------- class MyClassB(): def __init__(self,arg): self.name = arg b1 = MyClassB("Yamamoto") #引数有りのインスタンス化 b2 = MyClassB("Saitou") print (b1.name) #Yamamoto print (b2.name) #Saitou b1.name='フィギア' b2.name='中年少年' print (b1.name) #フィギア print (b2.name) #中年少年 ''' ID:MyClassA.counter 505986456 MyClassA.counter 1 ID:MyClassA.counter 505986472 MyClassA.counter 2 ID:MyClassA.counter 505986488 Tanaka 変態 秋葉原 a1.counter 2 MyClassA.counter 2 a2.counter 2 MyClassA.counter 2 ID:a1.counter 505986488 ID:a2.counter 505986488 ID:MyClassA.counter 505986488 Yamamoto Saitou フィギア 中年少年 '''
class MyClassA: counter=0 #クラス変数(どのインスタンスにも共通の変数=おまけ) def __init__(self): #引数なし self.name = "" # インスタンス変数 self.counter+=1 print('ID:MyClassA.counter',id(MyClassA.counter)) #505986456 #0 a1 = MyClassA() print('MyClassA.counter',MyClassA.counter) print('ID:MyClassA.counter',id(MyClassA.counter)) #505986456 #0 a1.name = "Tanaka" #インスタンス化後代入 a2 = MyClassA() print('MyClassA.counter',MyClassA.counter) print('ID:MyClassA.counter',id(MyClassA.counter)) #505986456 #0 print (a1.name) print (a2.name ) #------------------------------------------------- a1.name='変態' a2.name='秋葉原' print (a1.name) print (a2.name) #print(counter) エラー print('a1.counter',a1.counter) #1(インスタンス変数) print('MyClassA.counter',MyClassA.counter) #0 print('a2.counter',a2.counter) #1(インスタンス変数) #print(b1.counter) エラー'MyClassB' object has no attribute 'counter' print('MyClassA.counter',MyClassA.counter) #0 #print(MyClassA.name) エラー'MyClassA' has no attribute 'name' #print(MyClassB.name) エラー'MyClassB' has no attribute 'name' print('ID:a1.counter',id(a1.counter)) #505986472 #1 print('ID:a2.counter',id(a2.counter)) #505986472 #2 print('ID:MyClassA.counter',id(MyClassA.counter)) #505986456 #2 #--------------------------------------------------------------------- class MyClassB(): def __init__(self,arg): self.name = arg b1 = MyClassB("Yamamoto") #引数有りのインスタンス化 b2 = MyClassB("Saitou") print (b1.name) #Yamamoto print (b2.name) #Saitou b1.name='フィギア' b2.name='中年少年' print (b1.name) #フィギア print (b2.name) #中年少年 ''' ID:MyClassA.counter 505986456 MyClassA.counter 0 ID:MyClassA.counter 505986456 MyClassA.counter 0 ID:MyClassA.counter 505986456 Tanaka 変態 秋葉原 a1.counter 1 MyClassA.counter 0 a2.counter 1 MyClassA.counter 0 ID:a1.counter 505986472 ID:a2.counter 505986472 ID:MyClassA.counter 505986456 Yamamoto Saitou フィギア 中年少年 '''
selfとは何?
クラスのインスタンスを指す
コード本文で現れないものがclassに出てきて、変数や関数にによってself.が付いたり付かなかったり?
# coding: utf-8 # アクセス制限を理解する class Player: def __init__(self, job, weapon): self.job = job self.__weapon = weapon def walk(self): print(self.job + "は荒野を歩いていた") self.__attack("スライム") def __attack(self, enemy): print(self.__weapon + "で" + enemy + "を攻撃") player1 = Player("戦士", "剣") player1.walk() 戦士は荒野を歩いていた 剣でスライムを攻撃
さっぱりわからない。紙に印刷して変数を線で結んで変化を確認するのが良い
変数を日本語に変えてみよう。変数名以外は同じ、問題なく動く
変数が漢字になったので一つずつ目で追ってみよう、印刷して線を引いて追うのが一番いい
# coding: utf-8 # アクセス制限を理解する __攻撃() class 伝説の勇者: def __init__(ピエール, 役割, 武器): ピエール.役割 = 役割 ピエール.__武器 = 武器 def 進軍(ピエール): print(ピエール.役割 + "は荒野を歩いていた") ピエール.__攻撃("スライム")#練習としてプライベートメソッドを呼び出してみる def __攻撃(ピエール, モンスター): #本文からは呼べないプライベートメソッド print(ピエール.__武器 + "で" + モンスター + "を攻撃した") #モンスターは引数名で、'スライム'が中身として渡される ピエール = 伝説の勇者("戦士", "ハッカパイプ") ピエール.進軍() -------------------------------- ピエールは荒野を歩いていた ハッカパイプでスライムを攻撃した
一人の勇士ピエールが伝説の勇者というクラスに出世する物語
冒険の書によれば
ピエール = 伝説の勇者(“戦士”, “ハッカパイプ”)
↑ “ハッカパイプ”を持つ”戦士”、”ピエール”は覚醒し「伝説の勇者クラス」となった
- 伝説の勇者ピエールは荒野を進軍した
- すると、進軍したときだけ現れるモンスター(’スライム’)に持っていた武器(’ハッカパイプ’)で攻撃した(__攻撃は、進軍中しか出来ない仕組みになっている)
selfを”ピエール”に置き換えて、”ピエール”で実体化するという荒業だが、問題ない。
これでクラスのオブジェクト仮引数と引数と__initとプライベート引数と、プライベート関数が理解できました。もう怖いのは、ハッカの代わりに葉っぱをパイプに詰めることだけですね。
コードはpaizaから、無料なのに最高。
プログラミング学習 > Python > Python3入門編 > Python入門編8: クラスを理解しよう > アクセス制限を理解しよう
コメント