在Java中,有public,protect,private等访问控制修饰符,python采用另一种方法(双下划线,单下划线)来访问控制类的内容。 双下线__相当于java中的private,单下划线_相当于protect。

双下划线开头

可以把属性的名称前加上两个下划线。在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))

#创建实例hank
hank = Student('Hank', 60)

#调用实例方法
hank.print_score()

执行以上程序会输出如下结果:
Hank: 60

调用私有属性__name,报错,如下。

1
2
3
4
5
print("hank的属性__name的值:",hank.__name)
Traceback (most recent call last):
  File "main.py", line 14, in <module>
    print("hank的属性__name的值:",hank.__name)
AttributeError: 'Student' object has no attribute '__name'

私有变量可以在在类内部定义方法进行读取。利用类的特性@property也可以访问私有字段。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Student(object):
    def __init__(self, name, score):
        self.__name = name
        self.__score = score

    @property
    def print_score(self):
        return self.__score

#创建实例hank
hank = Student('Hank', 60)

#获取私有变量
print("实例hank的私有变量__score的值:",hank.print_score)

执行以上程序会输出如下结果:
实例hank的私有变量__score的值: 60

不能直接访问score是因为Python解释器对外把score变量改成了_Studentscore,所以,仍然可以通过_Studentscore来访问__score变量。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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))

#创建实例hank
hank = Student('Hank', 60)

#获取私有变量
print("实例hank的私有变量__name的值:",hank._Student__name)
print("实例hank的私有变量__score的值:",hank._Student__score)

执行以上程序会输出如下结果:

1
2
实例hank的私有变量__name的值 Hank
实例hank的私有变量__score的值 60

修改私有变量

有两种方法修改私有变量。
方法1 @property @方法名.setter修饰器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Student(object):
    def __init__(self, name):
        self.__name = name

    def print_score(self):
        print('%s' % (self.__name))

    @property
    def modify_attr(self):
        return self.__name

    @modify_attr.setter
    def modify_attr(self,name):
        self.__name = name

#创建实例hank
hank = Student('Hank')

#获取私有变量
print("修改前实例hank的私有变量__name的值:",hank._Student__name)
hank.modify_attr = "Tom"
print("修改后实例hank的私有变量__name的值:",hank._Student__name)

执行以上程序会输出如下结果:

1
2
修改前实例hank的私有变量__name的值 Hank
修改后实例hank的私有变量__name的值 Tom

方法2 _ClassName__属性名 = NewValue方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
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))

#创建实例hank
hank = Student('Hank', 60)

#获取私有变量
print("修改前实例hank的私有变量__name的值:",hank._Student__name)
print("修改前实例hank的私有变量__score的值:",hank._Student__score)
hank._Student__name = "Tom"
hank._Student__score = 100
print("修改后实例hank的私有变量__name的值:",hank._Student__name)
print("修改后实例hank的私有变量__score的值:",hank._Student__score)

执行以上程序会输出如下结果:

1
2
3
4
修改前实例hank的私有变量__name的值 Hank
修改前实例hank的私有变量__score的值 60
修改后实例hank的私有变量__name的值 Tom
修改后实例hank的私有变量__score的值 100

私有方法

以__开头的方法。

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

#创建实例hank
hank = Student('Hank', 60)

#调用实例方法
hank.__print_score()

执行以上程序会输出如下结果:

1
2
3
4
Traceback (most recent call last):
  File "main.py", line 13, in <module>
    hank.__print_score()
AttributeError: 'Student' object has no attribute '__print_score'

私有方法,只能在类的内部才可以访问。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
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 show(self):
        self.__print_score()

#创建实例hank
hank = Student('Hank', 60)

#调用实例方法
hank.show()

执行以上程序会输出如下结果: Hank: 60

不能直接调用print_score是因为Python解释器对外把print_score方法改成了_Studentprint_score,所以,仍然可以通过_Studentprint_score来访问__print_score变量。

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

#创建实例hank
hank = Student('Hank', 60)

#调用实例方法
hank._Student__print_score()

执行以上程序会输出如下结果: Hank: 60

单下划线开头

以一个下划线开头的实例变量名,比如_name,这样的实例变量外部是可以访问的。
以一个下划线开头的实例方法名,比如__print_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 _print_score(self):
    print('%s: %s' % (self._name, self._score))

#创建实例hank
hank = Student('Hank', 60)

#调用实例属性
print("hank的属性_name的值:",hank._name)
print("hank的属性_score的值:",hank._score)

#调用实例方法
hank._print_score()

执行以上程序会输出如下结果:

1
2
3
hank的属性_name的值: Hank
hank的属性_score的值: 60
Hank: 60

转载请注明本网址。