1 特殊方法(魔术方法)
- 特殊方法都是以双下划线开头双下划线结尾的方法
- 特殊⽅法都是形如 _ _ xxx _ _()这种形式
- 特殊方法不需要我们自己调用
- 特殊方法会在特殊的时候自动调用
- 学习特殊方法
- 特殊方法什么时候调用
- 特殊方法有什么作用
- 类中的代码块先执行,而且只执行了一次
创建流程
p1 = Person()
1.创建一个变量
2.在内存中创建一个新的对象
3.执行类中的代码块(只执行一次)
3.init(self)方法执行
class Person:
# 在类中可以定义一些特殊方法()魔术方法
# 特殊方法都是以双下划线开头双下划线结尾的方法
# 特殊方法不需要我们自己调用
def __init__(self):
print('init方法执行了')
print('Person代码块中的代码')
def speak(self):
print('大家好,我是%s'%self.name)
p1 = Person()
p2 = Person()
p3 = Person()
p4 = Person()
结果
Person代码块中的代码
init方法执行了
init方法执行了
init方法执行了
init方法执行了
init在什么时候调用
- init会在对象创建以后立即执行
- init会像新创建的对象初始化属性
class Person:
# 在类中可以定义一些特殊方法()魔术方法
# 特殊方法都是以双下划线开头双下划线结尾的方法
# 特殊方法不需要我们自己调用
def __init__(self,name):
# 通过self向新创建的对象中初始化属性
self.name = name
# print(self)
# print('init方法执行了')
#
# print('Person代码块中的代码')
def speak(self):
print('大家好,我是%s'%self.name)
p1 = Person('葫芦娃')
p2 = Person('钢铁侠')
p3 = Person('绿巨人')
p4 = Person('美国队长')
print(p1.name)
print(p2.name)
print(p3.name)
print(p4.name)
p2.speak()
结果
葫芦娃
钢铁侠
绿巨人
美国队长
大家好,我是钢铁侠
有上述例子得出,类的基本结构
# 类的基本结构
'''
class 类名([父名])
公共的属性……
# 对象的初始化方法
def __init__(self,……)
代码块
# 其他的方法
def m1(self,……)
代码块
def m1(self,……)
代码块
……
'''
-
我们要增加数据的安全性:
属性不能随意修改(我让你改你才能改,不让你改你就别改)
属性不能改为任意的值
2 封装
- 封装是面向对象的三大特性之一
- 封装指的是隐藏对象中一些不希望被外部访问到的属性或方法
- 如何隐藏对象中的一个属性
将对象的属性名,修改为一个外部不知道的名字 - 如何获取(修改)对象当中的属性
我们可以提供一个getter和setter方法是外部可以访问和修改属性 - 使⽤封装,确实增加了类的定义的复杂程度,但是它也确保了数据的安全
- 隐藏属性名,使调⽤这⽆法随意的修改对象中的属性
- 增加了getter()和setter()⽅法,很好控制属性是否是只读的
- 使⽤setter()设置属性,可以增加数据的验证,确保数据是正确的
- 使⽤getter()⽅法获取属性,使⽤setter()⽅法设置属性可以在读取属
性和修改属性的同时做⼀些其他的处理
class Dog:
def __init__(self,name,age):
self.hidden_name = name # 隐藏名字
self.hidden_age = age
def speak(self):
print('大家好,我是%s'%self.hidden_name)
def get_age(self): # getter方法
# get_name()用来获取对象的name属性
return self.hidden_age
def set_age(self,age):
# set_name()用来设置对象的name属性
self.hidden_age = age
d = Dog('德牧',5)
d.set_age(8)
print(d.get_age())
结果
8
添加修改条件,验证了3. 使⽤setter()设置属性,可以增加数据的验证,确保数据是正确的
class Dog:
def __init__(self,name,age):
self.hidden_name = name # 隐藏名字
self.hidden_age = age
def speak(self):
print('大家好,我是%s'%self.hidden_name)
def get_age(self): # getter方法
# get_name()用来获取对象的name属性
return self.hidden_age
def set_age(self,age):
# set_age()用来设置对象的age属性
if age > 0:
self.hidden_age = age
d = Dog('德牧',5)
d.set_age(-8)
print(d.get_age())
结果
5
- 使⽤getter()⽅法获取属性,使⽤setter()⽅法设置属性可以在读取属
性和修改属性的同时做⼀些其他的处理
class Dog:
def __init__(self,name,age):
self.hidden_name = name # 隐藏名字
self.hidden_age = age
def speak(self):
print('大家好,我是%s'%self.hidden_name)
def get_age(self): # getter方法
# get_name()用来获取对象的name属性
print('用户获取了属性')
return self.hidden_age
def set_age(self,age):
# set_age()用来设置对象的age属性
print('用户修改了属性')
if age > 0:
self.hidden_age = age
d = Dog('德牧',5)
d.set_age(8)
print(d.get_age())
结果
用户修改了属性
用户获取了属性
8
- 可以为对象的属性使用双下划线开头–>__xxx
- 双下划线开头的属性是对象的隐藏属性,隐藏属性只能在类的内部访问,无法通过外部访问
隐藏属性是python自动为属性改了一个名字
- 实际改的名字是:_类名__属性名[^__name --> _Person__name]
# 实际改的名字是 _类名__属性名[^__name --> _Person__name]
class Person:
def __init__(self,name):
self.__name = name
def get_name(self):
return self.__name
def set_name(self,name):
self.__name = name
p = Person('葫芦娃')
print(p._Person__name)
# p.set_name('钢铁侠')
p._Person__name = '绿巨人'
print(p.get_name())
结果
葫芦娃
绿巨人
- 一般你要告诉别人这个属性是用来封装的 以 _开头
# 一般你要告诉别人这个属性是用来封装的 以 _开头
class Person:
def __init__(self,name):
self._name = name
def get_name(self):
return self._name
def set_name(self,name):
self._name = name
p = Person('葫芦娃')
# print(p._Person__name)
# # p.set_name('钢铁侠')
# p._Person__name = '绿巨人'
# print(p.get_name())
print(p._name)
结果
葫芦娃
- 一般情况,使用_开头的属性都是私有属性,没有特殊情况下不要修改私有属性
3 @property
- 我们可以使⽤@property装饰器来创建只读属性,@property装饰器会将⽅法转换为相同名称的只读属性,可以与所定义的属性配合使⽤,这样可以防⽌属性被修改
- property装饰器 用来将一个方法转换为对象的属性
这个防止属性被修改
class Person:
def __init__(self,name):
self._name = name # 对name做了封装
# property装饰器 用来将一个方法转换为对象的属性
@property
def name(self):
print('getter方法执行了')
# 这是一个getter()方法
return self._name
p = Person('葫芦娃')
# p.name = '钢铁侠' # AttributeError: can't set attribute 防止属性被修改
# print(p.name()) # TypeError: 'str' object is not callable
print(p.name)
结果
getter方法执行了
葫芦娃
如果想改怎么办
class Person:
def __init__(self,name):
self._name = name # 对name做了封装
# property装饰器 用来将一个方法转换为对象的属性
@property
def name(self):
print('getter方法执行了')
# 这是一个getter()方法
return self._name
# setter 方法的装饰器 @属性名.setter
@name.setter
def name(self,name):
self._name = name
p = Person('葫芦娃')
p.name = '钢铁侠'
print(p.name)
结果
getter方法执行了
钢铁侠