ホームページ  >  記事  >  バックエンド開発  >  Python オブジェクト指向のアクセス制限

Python オブジェクト指向のアクセス制限

不言
不言オリジナル
2018-04-14 10:21:251740ブラウズ

この記事で共有する内容は、Python のオブジェクト指向のアクセス制限に関するもので、必要な場合は参照できます。

クラス内に属性とメソッドを含めることができます。インスタンス変数メソッドによって呼び出されるメソッドはデータの操作に使用されるため、複雑な内部ロジックが隠蔽されます。

ただし、Student クラスの以前の定義から判断すると、外部コードは依然としてインスタンスの名前とスコア属性を自由に変更できます:

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)
100
120

内部属性が外部からアクセスされるのを防ぎたい場合は、次の 2 文字を追加できます。属性の名前の前にアンダースコア __ を付けます。Python では、インスタンスの変数名が __ で始まる場合、その変数は内部からのみアクセスでき、外部からはアクセスできません。学生クラス:

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'
改完后,对于外部代码来说,没什么变动,但是已经无法从外部访问实例变量.__name和实例变量.__score了:
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: &#39;Student&#39; object has no attribute &#39;__name&#39;

これにより、外部コードがオブジェクトの内部状態を自由に変更できないことが保証され、アクセス制限の保護によりコードがより堅牢になります。

しかし、外部コードが名前とスコアを取得したい場合はどうなるでしょうか? get_name や get_score などのメソッドを Student クラスに追加できます:

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(&#39;Boyuan Zhou&#39;,100)
print(bart.get_name())
#Boyuan Zhou

外部コードによるスコアの変更を許可したい場合はどうすればよいでしょうか? set_score メソッドを Student クラスに追加できます:

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 を通じて直接変更できます。なぜ、メソッドを定義するのにそんなに苦労するのでしょうか?メソッド内でパラメーターをチェックして、無効なパラメーターを渡さないようにすることができるためです:

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(&#39;bad score&#39;)

Python では、変数名は __xxx___ に似ていることに注意してください。つまり、変数名は 2 つのアンダースコアで始まり、2 つのアンダースコアで終わります。最後の変数は特殊変数です。特殊変数はプライベート変数ではないため、__name__ や __score__ などの変数名は使用できません。

場合によっては、_name などのアンダースコアで始まるインスタンス変数名が表示されますが、そのようなインスタンス変数は外部からアクセスできます。

二重アンダースコアで始まるインスタンス変数は必ずしも外部からアクセスできないのでしょうか?実際はそうではありません。__name に直接アクセスできない理由Python インタープリターは外部で __name 変数を _Student__name に変更したため、_Student_name を通じて __name 変数に引き続きアクセスできます:

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(&#39;bad score&#39;)
bart = Student('Boyuan Zhou',100)print(bart._Student__name)
print(bart.get_name())
#Boyuan Zhou
#Boyuan Zhou

ただし、Python インタープリターのバージョンが異なると __name が異なる変数名に変更される可能性があるため、これを行わないことを強くお勧めします。


関連する推奨事項:

Python オブジェクト指向のクラスと例





以上がPython オブジェクト指向のアクセス制限の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。