python3 class / self scope instance object

クラスの説明がわかりやすい

クラス変数インスタンス変数

 

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: クラスを理解しよう > アクセス制限を理解しよう

コメント

タイトルとURLをコピーしました