在类中我们可以定义一些特殊方法 它的打印结果为: 我们这样子写没有问题,我们只给p1这个对象赋予了名字,其他对象都没,我们能正常输出结果: 我们尝试定义一个车类 打印结果: 封装是面向对象的三大特征之一。 输出:大豺狗 输出结果: 输出结果: 修改成功: 这也不难理解,把年龄修改成功了 并没有修改成功 访问不到,报错了 没报错 输出结果: 报错 输出
面向对象
特殊方法
这些特殊方法形如__开头__,如__ init__
特殊方法不需要我们自己调用,特殊方法会在特殊的时候自动调用,它先执行类中的代码块,在执行init方法中的代码块:class Person: def __init__(self): print('hello') print('类中的代码块') p1=Person() p2=Person() p3=Person()
先执行类中的代码块,在执行init方法中的代码块在在执行init方法中的代码块。
我们再来看下面这个代码class Person: def speak(self): print('大家好,我是%s'%self.name) p1=Person() p1.name='钢铁侠' p2=Person() p3=Person() p1.speak()
这样我们创建了多个对象,但我们只给一个对象赋了值,那其他的对象的赋值我们是不是会很容易忘呢,这样的话我们又该怎么办呢?
这时我们就得用到特殊方法了:class Person: def __init__(self,name): self.name=name def speak(self): print('大家好,我是%s'%self.name) p1=Person() p1.name='钢铁侠' p2=Person() p3=Person() p1.speak()
我们加了两行代码,就报错了,说我们少了一个‘name’参数,所以这样就解决了我们会忘记赋值的问题,如果我们没有赋值,那么就会报错。类的基本结构
class 类名([父类]): 公共属性... # 对象的初始化方法 def __init__(self,.....) pass #其他的方法 def method1(self): pass def method2(self): pass
封装的引入
属性:name,color
方法:run(),laba()class Car: def __init__(self,color,name): self.color=color self.name=name def laba(self): print('%s 滴滴滴滴'%self.name) def run(self): print('汽车开始跑了') c=Car('白色','大奔') c.laba() c.run()
这很容易理解,没多大问题,我们来这么改一下class Car: def __init__(self,color,name): self.color=color self.name=name def laba(self): print('%s 滴滴滴滴'%self.name) def run(self): print('汽车开始跑了') c=Car('白色','大奔') c.name='大狼狗' c.laba() c.run()
看看这个结果,这就不太符合常理了,大狼狗只会汪汪汪汪,他不会发出滴滴滴滴的声音。
我们是通过对象.属性名的方式修改了属性的值。
那么我们现在需要通过一种方式来增强数据的安全性
1.属性不能随意修改(我让你改,你才能改)
2.属性不能改为任意值
这个时候我们就需要用到封装封装
封装就是指隐藏对象中的一些不希望被外部访问到的属性或方法。class Dog: def __init__(self,name): self.name=name d=Dog('大狼狗') d.name='大豺狗' print (d.name)
说明我们把属性修改了,那么我们现在就是需要将对象的属性名修改为一个外部不知道的名字。class Dog: def __init__(self,name): self.hidden_name=name def speak(self): print('大家好,我是%s'%self.hidden_name) d=Dog('大狼狗') d.name='大豺狗' d.speak()
并没有修改成大豺狗
那当然我们还可以这样来修改属性:class Dog: def __init__(self,name): self.hidden_name=name def speak(self): print('大家好,我是%s'%self.hidden_name) d=Dog('大狼狗') d.hidden_name='大豺狗' d.speak()
不是说不能修改吗,这这这怎么就成功了呢???
这个时候就值得我们注意了:所谓封装,并不是完全隐藏属性的名字,遇到 self.hidden_name=name这种情况,就是说千万不要修改这个属性。
如果非要修改属性呢?
我们提供了一个getter和setter方法使外部可以访问到属性并修改。class Dog: def __init__(self,name): self.hidder_name=name def speak(self): print('大家好,我是%s'%self.hidder_name) def get_name(self): #get_name()用来获取对象的name属性值 return self.hidder_name def set_name(self,name): #set_name()用来修改对象的name属性值 self.hidder_name=name d=Dog('大狼狗') print(d.get_name()) d.set_name('大黑背') print (d.get_name()) d.speak()
使用封装确实增加了类的定义的复杂程度,但是他也确保了数据的安全
class Dog: def __init__(self,name,age): self.hidder_name=name self.hidder_age=age def get_name(self): return self.hidder_name def set_name(self,name): self.hidder_name=name def get_age(self): return self.hidder_age def set_age(self,age): self.hidder_age=age d=Dog('大狼狗',5) print(d.get_age()) d.set_age(6) print(d.get_age())
那如果我们这样呢class Dog: def __init__(self,name,age): self.hidder_name=name self.hidder_age=age def get_name(self): return self.hidder_name def set_name(self,name): self.hidder_name=name def get_age(self): return self.hidder_age def set_age(self,age): self.hidder_age=age d=Dog('大狼狗',5) print(d.get_age()) d.set_age(-6) print(d.get_age())
他也修改了,但是我们的年龄也不可能为负值呀,这个时候就可以在setter()方法上做一些修改了class Dog: def __init__(self,name,age): self.hidder_name=name self.hidder_age=age def get_name(self): return self.hidder_name def set_name(self,name): self.hidder_name=name def get_age(self): return self.hidder_age def set_age(self,age): if age>0: self.hidder_age=age d=Dog('大狼狗',5) print(d.get_name()) print(d.get_age()) d.set_age(-6) print(d.get_age())
我们来对getter()方法和setter()方法做一些其他的处理class Dog: def __init__(self,name,age): self.hidder_name=name self.hidder_age=age def get_name(self): return self.hidder_name def set_name(self,name): self.hidder_name=name def get_age(self): print('用户读取了属性') return self.hidder_age def set_age(self,age): print('用户修改了属性') if age>0: self.hidder_age=age d=Dog('大狼狗',5) print(d.get_name()) print(d.get_age()) d.set_age(6) print(d.get_age())
我们还可以为对象属性使用__(双下划线)的方式来封装,如__name
双下划线的属性是对象的隐藏属性,隐藏属性只能在类的内部访问,无法通过对象访问
隐藏属性只不过是python自动给属性起了另外的一个名字,这个名字叫做 _类名__属性名
使用 __(双下划线)开头的属性,实际上我们依然是可以在外部访问的,所以这种方式一般不用,一般对属性进行封装,都是以 _(单下划线)的方式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.get_name()) print(p.__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.get_name()) print(p._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.get_name()) print(p._name)
property装饰器
class Person: def __init__(self,name): self._name=name @property def name(self): return self._name p=Person('葫芦娃') print(p.name())
我们修改为class Person: def __init__(self,name): self._name=name @property def name(self): return self._name p=Person('葫芦娃') print(p.name)
@property 创建的只读属性,这个装饰器会将方法转换为相同名称的只读属性
如果要修改呢class Person: def __init__(self,name): self._name=name @property def name(self): print('get方法执行了') return self._name @name.setter def name(self,name): self._name=name p=Person('葫芦娃') p.name='蝙蝠侠' print(p.name)
如果我们不使用@name.setter我们来看看是什么情况class Person: def __init__(self,name): self._name=name @property def name(self): print('get方法执行了') return self._name def name(self,name): self._name=name p=Person('葫芦娃') p.name='蝙蝠侠' print(p.name)
这看着是修改成功了,但细品一下你会发现他没有执行getter方法,这说明他并不是修改了属性值,他只是创建了这么一个对象的属性值。
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算