1.特殊方法
-
在类中可以定义一些特殊方法也称为魔术方法
-
在类中可以定义一些特殊方法也称为魔术方法
-
特殊方法都是形如 __ xxx__()这种形式
-
特殊方法不需要我们调用,特殊方法会在特定时候自动调用
引入
class Person:
# name ='hhh'
def speak(self):
print('大家好,我叫%s'%self.name)
p1=Person()
#手动添加name属性
p1.name='hhh'
p2=Person()
p2.name='www'
p3=Person()
p3.name='YYY'
p3.speak()#大家好,我叫YYY
学习特殊方法
- 特殊方法什么时候调用
- 特殊方法有什么用
class Person:
# 在类中可以定义一些特殊方法(魔术方法)
# 特殊方法 _开头_结尾
# 特殊方法不需要自己调用
#特殊方法会在特殊时刻自己调用
def __init__(self):
print('hello')
p1=Person()#hello
p1=Person()#hello
创建流程
- 1.创建变量
- 2.在内存中创建一个新的对象
- 3.先执行类中的代码块(执行一次)
- 4 . _ init_(self)方法执行
class Person:
def __init__(self):
print('hello')#后
print('123')#先
p1=Person()
加工对比
class Person:
def __init__(self):
self.name='hhh'
def speak(self):
print('大家好,我叫%s'%self.name)
p1=Person()
p1.speak()
#更容易修改
class Person:
def __init__(self,name):
self.name=name
def speak(self):
print('大家好,我叫%s'%self.name)
p1=Person('hhh')
p2=Person('www')
p3=Person('yyy')
p1.speak()
2.封装
引入:
class Car():
def __init__(self,name,color):
self.name=name
self.color=color
def run(self):
print('汽车开始跑了')
def laba(self):
print('%s滴滴滴滴'%self.name)
c=Car('大奔','白色')
#可以随意修改
c.name='法拉利'
c.run()
c.laba()
- 出现封装的原因:我们需要一种方式来增强数据的安全性
• 1. 属性不能随意修改
• 2. 属性不能改为任意的值 - 封装是面向对象的三大特性之一
- 封装是指隐藏对象中一些不希望被外部所访问到的属性或方法
如何隐藏对象的属性:
将对象的属性名修改为外部不知道的名字
class Dog():
def __init__(self,name):
self.hidden_name=name
def speak(self):
print('大家好,我是%s'%self.hidden_name)
d=Dog('hhh')
d.name='www'
d.speak()#大家好,我是hhh
d.hidden_name='yyy'
d.speak()#大家好,我是yyy
- 我们也可以提供给一个getter()和setter()方法是外部可以访问到属性
• getter() 获取对象中指定的属性
• setter() 用来设置对象指定的属性 - 使用封装,确实增加了类的定义的复杂程度,但是它也确保了数据的安全
• 1. 隐藏属性名,使调用这无法随意的修改对象中的属性
• 2. 增加了getter()和setter()方法,很好控制属性是否是只读的
• 3. 使用setter()设置属性,可以在呢及数据的验证
• 4. 使用getter()方法获取属性,使用setter()方法设置属性可以在读取属性和修改属性的同时做一些其他的处理
class Dog():
def __init__(self,name):
self.hidden_name=name
def get_name(self):
#get_name()用来获取对象的name属性
return self.hidden_name
def set_name(self,name):
#set_name()用来设置对象的name属性
self.hidden_name=name
def speak(self):
print('大家好,我是%s'%self.hidden_name)
d=Dog('hhh')
print(d.get_name())#hhh
d.speak()#大家好,我是hhh
d.set_name('www')
print(d.get_name())#www
d.speak()#大家好,我是www
但,也可找到外部不知道的名字进行修改
class Person():
def __init__(self,name):
self.hidden_name=name
def get_name(self):
#get_name()用来获取对象的name属性
return self.hidden_name
def set_name(self,name):
#set_name()用来设置对象的name属性
self.hidden_name=name
p=Person('hhh')
p.hidden_name='yyy'
print(p.get_name())#yyy
- 可以为对象的属性使用双下划线开头 __ xxx 。
- 双下划线开头的属性,是对象的隐藏属性,隐藏属性只能在类的内部访问,无法通过对象访问
- 其实隐藏属性只不过是Python自动为属性改了一个名字 --> _类名__属性名 例如 __name -> _Person__name
class Person():
def __init__(self,name):
self.__name=name
def get_name(self):
#get_name()用来获取对象的name属性
return self.__name
def set_name(self,name):
#set_name()用来设置对象的name属性
self.__name=name
p=Person('hhh')
#print(__name)#name '__name' is not defined
print(p._Person__name)#hhh
print(p.get_name())#hhh
p.set_name('www')
print(p._Person__name)#www
p.hidden_name='yyy'
print(p._Person__name)#www
print(p.get_name())#www
p.__name='yyy'
print(p.get_name())#www
- 这种方式实际上依然可以在外部访问,所以这种方式我们一般不用。
- 一般我们会将一些私有属性以_开头
一般情况下,使用_开头的属性都是私有属性,没有特殊情况下不要修改私有属性
3.property装饰器 知识点
- 我们可以使用**@property装饰器来创建只读属性,@property装饰器会将方法转换为相同名称的只读属性**,可以与所定义的属性配合使用,这样可以防止属性被修改
区别:
引入:无
print(p.name())
class Person():
def __init__(self,name):
self._name=name
def name(self):
print('getter方法执行了')
#getter()方法
return self._name
p=Person('hhh')
print(p.name())
引入:@property装饰器
print(p.name)
class Person():
def __init__(self,name):
self._name=name
#@property用来将一个方法转变为对象的属性
@property
def name(self):
print('getter方法执行了')
#getter()方法
return self._name
@name.setter
def name(self,name):
self._name=name
p=Person('hhh')
print(p.name)
p.name='www'
print(p.name)
总结: