この記事で共有する内容は、Python のオブジェクト指向のアクセス制限に関するもので、必要な場合は参照できます。
クラス内に属性とメソッドを含めることができます。インスタンス変数メソッドによって呼び出されるメソッドはデータの操作に使用されるため、複雑な内部ロジックが隠蔽されます。
ただし、Student クラスの以前の定義から判断すると、外部コードは依然としてインスタンスの名前とスコア属性を自由に変更できます:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Student(object):
def __init__(self,name,score):
self.name = name
self.score = score
def print_score(self):
print ('%s:%s'%(self.name,self.score))
def get_grade(self):
if self.score >=90:
return 'A'
elif self.score>=600:
return 'B'
else :
return 'C'
bart = Student('Boyuan Zhou',100)
print (bart.score)
bart.score=120
print (bart.score)
|
ログイン後にコピー
内部属性が外部からアクセスされるのを防ぎたい場合は、次の 2 文字を追加できます。属性の名前の前にアンダースコア __ を付けます。Python では、インスタンスの変数名が __ で始まる場合、その変数は内部からのみアクセスでき、外部からはアクセスできません。学生クラス:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Student(object):
def __init__(self,name,score):
self.__name = name
self.__score = score
def print_score(self):
print ('%s:%s'%(self.__name,self.__score))
def get_grade(self):
if self.__score >=90:
return 'A'
elif self.__score>=600:
return 'B'
else :
return 'C'
|
ログイン後にコピー
1 | 改完后,对于外部代码来说,没什么变动,但是已经无法从外部访问实例变量.__name和实例变量.__score了:
|
ログイン後にコピー
1 2 3 4 5 | bart = Student('Boyuan Zhou',100)
print (bart.__name)Traceback (most recent call last):
File "F:/mycompany/mycompany/schooldemo.py" , line 16, in <module>
print (bart.__name)
AttributeError: 'Student' object has no attribute '__name'
|
ログイン後にコピー
これにより、外部コードがオブジェクトの内部状態を自由に変更できないことが保証され、アクセス制限の保護によりコードがより堅牢になります。
しかし、外部コードが名前とスコアを取得したい場合はどうなるでしょうか? get_name や get_score などのメソッドを Student クラスに追加できます:
1 2 3 4 5 6 7 8 9 10 11 12 | class Student(object):
def __init__(self,name,score):
self.__name = name
self.__score = score
def get_name(self):
return self.__name
def get_score(self):
return self.__score
bart = Student('Boyuan Zhou',100)
print (bart.get_name())
#Boyuan Zhou
|
ログイン後にコピー
外部コードによるスコアの変更を許可したい場合はどうすればよいでしょうか? set_score メソッドを Student クラスに追加できます:
1 2 3 4 5 6 7 8 9 | class Student(object):
def __init__(self,name,score):
self.__name = name
self.__score = score
def get_name(self):
return self.__name def get_score(self):
return self.__score
def set_score(self,score):
self.__score=score
|
ログイン後にコピー
疑問に思うかもしれませんが、元のメソッドは bart.score = 59 を通じて直接変更できます。なぜ、メソッドを定義するのにそんなに苦労するのでしょうか?メソッド内でパラメーターをチェックして、無効なパラメーターを渡さないようにすることができるためです:
1 2 3 4 5 6 7 8 9 10 11 12 13 | class Student(object):
def __init__(self,name,score):
self.__name = name
self.__score = score
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_score(self,score):
if 0 <=score <= 100:
self.__score=score
else :
raise ValueError('bad score')
|
ログイン後にコピー
Python では、変数名は __xxx___ に似ていることに注意してください。つまり、変数名は 2 つのアンダースコアで始まり、2 つのアンダースコアで終わります。最後の変数は特殊変数です。特殊変数はプライベート変数ではないため、__name__ や __score__ などの変数名は使用できません。
場合によっては、_name などのアンダースコアで始まるインスタンス変数名が表示されますが、そのようなインスタンス変数は外部からアクセスできます。
二重アンダースコアで始まるインスタンス変数は必ずしも外部からアクセスできないのでしょうか?実際はそうではありません。__name に直接アクセスできない理由Python インタープリターは外部で __name 変数を _Student__name に変更したため、_Student_name を通じて __name 変数に引き続きアクセスできます:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Student(object):
def __init__(self,name,score):
self.__name = name
self.__score = score
def get_name(self):
return self.__name
def get_score(self):
return self.__score
def set_score(self,score):
if 0 <=score <= 100:
self.__score=score
else :
raise ValueError('bad score')
bart = Student( 'Boyuan Zhou' ,100) print (bart._Student__name)
print (bart.get_name())
#Boyuan Zhou
#Boyuan Zhou
|
ログイン後にコピー
ただし、Python インタープリターのバージョンが異なると __name が異なる変数名に変更される可能性があるため、これを行わないことを強くお勧めします。
関連する推奨事項:
Python オブジェクト指向のクラスと例
以上がPython オブジェクト指向のアクセス制限の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。