类的特殊方法
在类中我们可以定义一些特殊方法
这些特殊方法他的格式是以:(__开头__结尾)的方法
注意:这些特殊方法不需要自己调用自己
#创建一个类
class Person():
#创建一个特殊方法
def __init__(self):
print('Python')
#创建一个类的实例对象
p1 = Person()
p1.__init__()
运行结果:
Python
Python
运行结果为什么会显示两个Python呢?因为这些特殊方法不需要我们自己去调用,不用尝试着去调用这些特殊方法
类的执行流程
1、先创建一个类(当类中有print时)
2、在内存中创建一个新的对象(解析器会自动在内存中生成新的内存)
3、注意(先执行类中的代码)(注意:定义在类中的代码只执行一次,当定义多个实例对象等于类时,结果也只是执行一次)
4、__init __(self)特殊方法执行
class Person():
print('执行类代码块')
def __init__(self,name):
self.name = name
def speak(self):
print('你好我是%s'%self.name)
p1 = Person('光头强')
p1.speak() # 执行类代码块 你好我是光头强
p2 = Person('蜘蛛侠') # 你好我是蜘蛛侠
p2.speak()
#总结:为什么结果不一样呢,因为执行类中的代码块的代码(只在类定义的时候执行一次)当定义两个实例对象后,结果也是一样
运行结果:
执行类代码块
你好我是光头强
你好我是蜘蛛侠
特殊方法有什么用呢? 实例属性
每个实例对象都有自己的属性,通过“self.”变量名定义,实例属性属于特定的实例。实例变量在类的内部通过“self.”访问,在外部通过对象实例访问。
实例属性初始化:通常在__init__ 方法中利用“self.”对实例属性进行初始化。
self.实例变量名=初始值
在其他实例函数中
self.实例变量名=值
#创建一个类
class person():
#创建一个特殊方法,并把参数传进去
def __init__(self,name):
self.name = name #把方法不写死,想调用谁就传谁
#创建一个方法
def speak(self):
print('你好我是%s'%self.name)
#创建一个实例对象,并传参
p1 = person('光头强')
p1.speak()
运行结果:
你好我是光头强
封装
封装是面向对象的三大特征之一
封装是指隐藏对象中一些不希望被外部访问到的属性和方法
隐藏对象的属性:(将对象的属性修改成外部不知道的名字)
如何获取(修改)对象当中的属性(需要提供一个getter和setter方法使外部可以访问到的属性)
#创建一个类
class Person():
#创建一个特殊方法
def __init__(self,name):
self.hidden = name
#创建一个方法
def speak(self):
print('大家好,我是%s'%self.hidden)
#get_name(self)获取对象的指定属性(get_属性名)
#定义一个实例对象来调用类
p1 =Person('光头强')
p1.name = '熊大熊二'
p1.speak()
运行结果
大家好,我是光头强
总结:为什么运行结果不是熊大熊二呢,那是因为在特殊方法中我们定义的name的属性值是已经封装起来的
读取封装的值:
#创建一个类
class Person():
#创建一个特殊方法
def __init__(self,name):
self.hidden = name
#创建一个方法
def speak(self):
print('大家好,我是%s'%self.hidden)
#get_name(self)获取对象的指定属性(get_属性名)
def get_name(self):
return self.hidden
#定义一个实例对象来调用类
p1 =Person('光头强')
print(p1.get_name())
运行结果:
光头强
使用封装的好处
使用封装确实增加了类定义的复杂程度,但是它确保了我们数据的安全性
1:隐藏了属性名,使用者无法随意的修改对象的属性
2:增加了getter和setter方法之后,很好的控制了属性是否是只读的
如果你希望属性只可读的,则可以直接去调用getter方法
如果你希望属性不能被外部访问,则可以去调用setter方法
3:使用setter方法设置属性,可以增强数据的验证,确保数据的正确
4:使用getter方法获取属性,使用setter方法设置属性,我们可以在读取属性和修改属性的时候做一些其他操作
# 创建一个类
class Person():
# 创建一个特殊方法
def __init__(self, name, ord):
self.hiddern_name = name
self.hiddern_ord = ord
# 创建一个方法
def speak(self):
print('你好我是%s' % self.hiddern_name)
print('你好我的身高是%s' % self.hiddern_ord)
# get_name用来表示只读属性
def get_name(self):
return self.hiddern_name
# 同理
def get_ord(self):
return self.hiddern_ord
# set_name(self,属性名)
def set_name(self, name):
self.hiddern_name = name
# 同理(但我们身高是正数,要做判断)
def set_orl(self, ord):
if ord > 0:
self.hiddern_ord = ord
# 创建一个实例对象来获取类方法
p1 = Person('蜘蛛侠',180)
p1.speak()
# 获取类中的属性值
print(p1.get_ord())
print(p1.get_name())
# 修改封装后的属性值
p1.set_name('光头强')
p1.set_orl(180)
p1.speak()
运行结果:
你好我是蜘蛛侠
你好我的身高是180
180
蜘蛛侠
你好我是光头强
你好我的身高是180
property()装饰器
通过property()装饰器来调用其属性和方法
class Person():
def __init__(self,name):
self._name = name
@property
def name(self):
print('getter方法执行了')
return self._name
#设置setter方法的装饰器 @属性名.setter
@name.setter
def name(self,name):
print('setter方法执行了')
self._name = name
p1 = Person('变形金刚')
p1.name = '孙悟空'
#为什么p1.name不加括号了呢,那是因为结合了两个装饰器的使用,调用的该对象名
print(p1.name)
运行结果:
setter方法执行了
getter方法执行了
孙悟空