类与对象
封装
封装就是指隐藏对象中一些不希望外部所访问到的属性或方法,即为了保证安全
1、hidden_name来隐藏属性
在定义类时,将属性或方法名修改为外部并不知道的名称,如下定义类
class People:
def __init__(self,name,age):
self.name = name
self.age = age
def hello(self):
print(f'大家好,我是{self.name}')
#实例化一个对象
d = People('张楠',18)
d.hello()
#直接可以修改类中的属性,不安全
d.name = '飞扬'
d.hello()
输出结果为:
在定义类时,将属性或方法名修改为外部并不知道的名称,如下定义类
class People:
def __init__(self,name,age):
self.hidden_name = name
self.hidden_age = age
def hello(self):
print(f'大家好,我是{self.hidden_name}')
#实例化一个对象
d = People('张楠',18)
d.hello()
#直接可以修改类中的属性,不安全
d.name = '飞扬'
d.hello()
输出结果为:
2、 setter、getter的使用
那么,此时对象如何知道和修改上面属性的值呢?
很简单,在类中定义用于修改和获取属性的方法 set_name、get_name
需要提供一个getter和setter方法使外部可以访问到属性
getter 获取对象中的指定属性(get_属性名)
setter 用来设置对象的指定属性(set_属性名)
class People:
def __init__(self,name,age):
self.hidden_name = name
self.hidden_age = age
def hello(self):
print(f'大家好,我是{self.hidden_name}')
# 用于实例化对象设置修改类属性的方法
def set_name(self, name):
self.hidden_name = name
# 用于实例化对象获取得到类属性的方法
def get_name(self):
return self.hidden_name
#实例化一个对象
d = People('张楠',18)
d.hello()
#外部使用get_name()方法来修改类中的属性
d.set_name('飞扬')
d.hello()
输出结果为:
- 可以在set_name中判断输出的合法性,比如age的大小,性别的合法;如下代码所示
def set_age(self,age):
if age > 0:
self.hidden_age = name
使用封装,确实增加了类的定义的复杂程度,但是它也确保了数据的安全性
- 1、隐藏了属性名,使调用者无法随意的修改对象中的属性
- 2、增加了getter和setter方法,很好的控制属性是否是只读的
- 如果希望属性是只读的,则可以直接去掉setter方法
- 如果希望属性不能被外部访问,则可以直接去掉getter方法
- 3、使用setter方法设置属性,可以增加数据的验证,确保数据的值是正确的在方法中判断年龄等属性的数值是否满足正常范围 >0
- 4、使用getter方法获取属性,使用setter方法设置属性;可以在读取属性和修改属性的同时做一些其他的处理
- 5、用getter方法可以表示一些计算的属性 圆面积 矩形面积
3、 __ 私有属性 _
使用访问修饰符:在Python中,有两种访问修饰符——公共和私有。公共变量和方法可以从类的任何实例中访问,而私有变量和方法只能从类内部访问。要定义私有变量和方法,请在变量或方法名称前加上两个下划线“__”。
可以为对象的属性使用双下划线开头,__xxx
-
双下划线开头的属性,是对象的隐藏属性,隐藏属性只能在类的内部访问,无法通过对象访问
-
其实隐藏属性只不过是Python自动为属性改了一个名字
-
实际上是将名字修改为了,_类名__属性名 比如 __name -> _Person__name,这样还是可以访问的
class People:
def __init__(self,name,age):
self.__name = name
self.__age = age
def hello(self):
print(f'大家好,我是{self.__name},我{self.__age}岁了')
#用于实例化对象设置修改类属性的方法
def set_name(self,name):
self.__name = name
#用于实例化对象获取得到类属性的方法
def get_name(self):
return self.__name
#实例化一个对象
d = People('张楠',18)
d.hello()
print(d._People__name)
# 其实可以通过如下方式修改私有属性的值,但是不会这么做,因为外部是不可以修改私有属性的值的
d._People__name = '飞扬'
d._People__age = '20'
d.hello()
输出结果为:
在这段代码中,你尝试通过访问 d._People__name 来修改私有属性 __name 的值,这是一种名称修饰的技巧。在Python中,通过这种方式访问双下划线前缀的属性或方法是合法的,但并不推荐这样做。这种方式是通过改变名称来绕过访问限制的,但它并不符合良好的编程实践,违背了封装的原则。
使用 __ 开头的属性,实际上依然可以在外部访问,所以这种方式我们一般不用 __
- 一般我们会将一些私有属性(不希望被外部访问的属性)以 _ 开头
- 一般情况下,使用 _ 开头的属性都是私有属性,没有特殊需要不要修改私有属性
class people:
def __init__(self,name,age):
self._name = name
self._age = age
def hello(self):
print(f'大家好,我是{self._name},我{self._age}岁了')
def set_name(self,name):
self._name = name
def get_name(self):
return self._name
#实例化一个对象
d = people('张楠',18)
d.hello()
#当然还是可以访问的,但是不会这么做
print(d._name)
d._name = '飞扬'
d.hello()
输出结果为: