很多面向对象的语言都提供了public,private和protected等关键字来限定类方法和属性的访问方式。其中,类的private成员是无法在类外被访问或调用的,他们只允许在类内进行访问和调用。类的public成员允许在类外被访问和调用。这一机制使得我们可以用公有(public)方法间接访问私有(private)实例变量来实现数据的封装。类的protected成员除了可以在类内访问和调用,还可以在子类中进行操作。这些保证了父类的一些资源可以被继承到子类。那么python中有类似的关键字来控制类内资源的访问权限吗?
答案是没有。python并没有提供类似的机制。一般我们采用在实例变量名和方法名前面加下滑线的方式来模仿private的机制。
1. public members
python类中的所有成员都是公有的。我们可以在类外访问并进行修改。
class Animal(object):
def __init__(self, name, num_of_legs):
self.name = name
self.num_of_legs = num_of_legs
cat = Animal("Kitty", 4)
print("Name:", cat.name)
cat.name = "Tiger"
print("Revised name:", cat.name)
## out put:
Name: Kitty
Revised name: Tiger
2. protected and private
按照前面介绍的,python类中的所有成员都是公有的,所以并没有严格意义上的受保护成员和私有成员。只有约定俗成的规则来区分。
protected members
我们通常通过在变量名前面加下划线的方式来表示其为“保护”变量,使它们只能在类内和子类内访问。但是事实上,我们还是可以在类外访问它们。
class Animal(object):
def __init__(self, name, num_of_legs):
self._name = name
self._num_of_legs = num_of_legs
仍然可以在类外直接访问:
cat = Animal("Kitty", 4)
print("Name:", cat._name)
cat._name = "Tiger"
print("Revised name:", cat._name)
## out put
Name: Kitty
Revised name: Tiger
因此,资深的程序员是不会在类外直接访问并修改带有下划线“_”的实例变量。按照惯例,这些带下划线的变量是被保护(protected)变量。
private members
同样的,私有变量是通过在变量名前面加双下划线来表示的。但是与受保护变量有些不一样的是:加双下滑线的变量会被python转换成object._class_variable。因此,用正常的方式是无法直接在类外访问这些变量(当然出于封装原则也不要直接在类外访问)。但是如果一定要访问的话,可以通过object._class_variable的方式访问。如下:
class Animal(object):
def __init__(self, name, num_of_legs):
self.__name = name
self.__num_of_legs = num_of_legs
直接用实例变量名访问会报错:
## 直接访问会出错
cat = Animal("Kitty", 4)
print("Name:", cat.__name)
cat.__name = "Tiger"
print("Revised name:", cat.__name)
## 报错信息如下
AttributeError: 'Animal' object has no attribute '__name'
我们可以通过以下方式访问:
cat = Animal("Kitty", 4)
print("Name:", cat._Animal__name)
cat._Animal__name = "Tiger"
print("Revised name:", cat._Animal__name)
## out put
Name: Kitty
Revised name: Tiger
网友评论