python 封装、绑定
2021-12-03 18:16
573 查看
[toc]
python 封装、绑定
面向对象共有三大特性:封装、继承、多态,这篇文章主要介绍一下类的封装,以及类的绑定。
封装:意思就是整合代码,将数据和功能整合到一起,起到规范代码的作用,更好的组织了项目的整体结构,减少了代码的冗余度,提升了可扩展性
类的封装主要分为数据封装、方法封装
1、数据、方法的封装
示例如下:
# 未封装前 name = 'HammerZe' age = 18 gender = 'male' print(f' name:{name}\n', f'age{age}\n', f'gender:{gender}') # 结果 name:HammerZe age:18 gender:male
这样看起来数据完全暴露出来,一个人的信息如此,如果多人的信息这样统计起来或者修改起来岂不是很麻烦?规定每个人的信息格式,整合起来首先比较方便,只需几行代码就可以显示一个人的全部信息
# 数据、方法封装 class Self_Info(): def __init__(self,name,age,gender): self.name = name self.age = age self.gender = gender # 方法/功能的封装 def view_info(self): print(f" name:{self.name}\n", f"age:{self.age}\n", f"gender:{self.gender}") obj = Self_Info('HammerZe',18,'male') obj.view_info() # 结果 name:HammerZe age:18 gender:male
看似封装后的代码多了很多,如果下次需要格式化输出其他人的信息,只需按照格式传参即可,不需要重新定义,重新写,这就规范了数据的一致性,比较好管理,上篇中介绍到类的增删查改,这样个人信息是不是也更好修改,不需要“牵一发而动全身”
2、隐藏属性
Python中,类内的属性是可以私有化的,就是把数据隐藏起来,对类外隐藏,类内可继续操作数据或方法。
私有属性格式:__属性名(数据/方法)
示例如下:
'''未私有前''' class Info(): address = 'shanghai' def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender def get_info(self): print(f" name:{self.name}\n", f"age:{self.age}\n", f"gender:{self.gender}\n", f"address:{self.address}") obj = Info('HammerZe',18,'male') obj.get_info() # 结果 name:HammerZe age:18 gender:male address:shanghai '''如果我们不想对类外开放个人地址,可以私有化''' # 属性私有 __address = 'shanghai' # 只需在数据名前加__,如果继续获取会报错 # 结果>>>AttributeError: 'Info' object has no attribute 'address' # 属性私有 class Info(): __address = 'shanghai' #底层:_Info__address def __init__(self, name, age, gender): self.name = name self.age = age self.gender = gender def get_info(self): print(f" name:{self.name}\n", f"age:{self.age}\n", f"gender:{self.gender}\n", f"address:{self.__address}") '''获取地址前加__''' obj = Info('HammerZe',18,'male') obj.get_info() # 结果 name:HammerZe age:18 gender:male address:shanghai '''私有了就不能获取到了吗?这个只是更改了数据的格式,如果想访问到可以通过获取数据格式,访问''' # 通过__dict__查看名称空间,发现__address格式变为_Info__address print(Info.__dict__) # 所以在类外通过获取到数据格式也是可以获取到的 print(obj._Info__address) # shanghai
- 注意!数据和方法的私有格式一样,知道底层的格式也是可以调用/获取到方法内和数据的信息,互联网没有绝对的安全
3、开放接口
- 类的私有原则是对外私有,但是在类内可以修改和继续使用,定义属性就是为了使用
计算器有很多种功能,但是我们在使用的时候只需输入数,通过计算就能得到结果,那么底层的数学原理我们不需要知道,只求结果即可,那么很多功能就可以私有,只暴露给用户结果!
# 属性私有 '''以幂运算为例''' class Calculator(): def __init__(self): self.num1 = int(input('请输入底数>>>:')) print(f'您输入的底数为{self.num1}') # 幂运算 def __pow(self,n): return self.num1**n def get_res(self): get_n = int(input('输入要计算幂运算的次方数>>>:')) res = self.__pow(get_n) print(f'幂运算结果为{res}') num = Calculator() num.get_res() # 结果 请输入底数>>>:22 您输入的底数为22 输入要计算幂运算的次方数>>>:1 幂运算结果为22 '''这样我们只需要输入数,幂运算的功能可以隐藏起来,只暴露给用户功能接口,返回结果'''
4、绑定方法
1、对象的绑定
class Info(): def __init__(self,name,age): self.name = name self.age = age '''绑定给对象的方法,对象来调用,会把自己当成第一个参数传到函数里面self''' def get_info(self): print(f'姓名:{self.name}|年龄:{self.age}') obj = Info('HammerZe',18) obj.get_info() # 结果 # 姓名:HammerZe|年龄:18
2、类的绑定(classmethod)
class Student(): def __init__(self,name,age): self.name = name self.age = age # @classmethod # def change(self): # obj = self.__class__('HammerZe', 18) # return obj '''上面注释掉这种方法等价与下面的方法''' @classmethod def change(cls): obj = cls('HammerZe', 18) return obj # 生成对象 stu = Student('ly',18) print(stu.__dict__) print(id(stu)) # 生成对象,再用新对象接收 obj = stu.change() print(obj.__dict__) print(id(obj)) '''stu.__class__.fun() 等价 Student.fun()''' # 类调用 obj1 = Student.change() print(obj1.__dict__) print(id(obj1))
3、非绑定方法(staticmethod)
''' 统计调用类,产生了多少个对象''' class Count_obj(): # 定义count count = 0 def __init__(self): Count_obj.count += 1 # 静态方法/非绑定方法:既不绑定给类,也不绑定给对象 @staticmethod def count_info(): print(f'产生了{Count_obj.count}个对象') # 调用类产生对象 obj = Count_obj() obj1 = Count_obj() obj2 = Count_obj() obj3 = Count_obj() obj4 = Count_obj() # 查看生成了多少个对象 Count_obj.count_info() '''注意,修改的是类体内的count,如果self.count只能在对象的名称空间中产生一次count,达不到统计的效果'''
5、property()函数及property装饰器
1、 property() 函数
格式:property(fget=None, fset=None, fdel=None, doc=None)
- fget:获取属性值的方法
- fset:设置属性值的方法
- fdel:删除属性值的方法
- doc:属性描述信息
示例如下:
class Student: def __init__(self): self._age = None def get_age(self): print('查看属性时执行的代码') return self._age def set_age(self, age): print('设置属性时执行的代码') self._age = age def del_age(self): print('删除属性时执行的代码') del self._age age = property(get_age, set_age, del_age, '学生年龄') student = Student() # 注意要用 类名.属性.__doc__ 的形式查看属性的文档字符串 print('查看属性的文档字符串:' + Student.age.__doc__) """ 查看属性的文档字符串:学生年龄 """ # 设置属性 student.age = 18 """ 设置属性时执行的代码 """ # 查看属性 print('学生年龄为:' + str(student.age)) """ 获取属性时执行的代码 学生年龄为:18 """ # 删除属性 del student.age """ 删除属性时执行的代码 """ print(student.__dict__) # {}
2、property装饰器
property装饰器可以将类中的函数‘伪装成’对象的数据属性,对象在访问该特殊属性时会触发功能的执行,然后将返回值作为本次的访问结果
@property
语法糖提供了比property()
函数更简洁直观的写法。被
@property
装饰的方法是获取属性值的方法,被装饰方法的名字会被用做属性名
。被
@属性名.setter
装饰的方法是设置属性值的方法。被
@属性名.deleter
装饰的方法是删除属性值的方法。
以下示例代码与使用
property()函数版本的代码等价:
class Student: def __init__(self): self._age = None @property def age(self): print('查看属性时执行的代码') return self._age @age.setter def age(self, age): print('设置属性时执行的代码') self._age = age @age.deleter def age(self): print('删除属性时执行的代码') del self._age student = Student() # 设置属性 student.age = 18 """ 设置属性时执行的代码 """ # 获取属性 print('学生年龄为:' + str(student.age)) """ 查看属性时执行的代码 学生年龄为:18 """ # 删除属性 del student.age """ 删除属性时执行的代码 """
3、注意!
- 可以省略设置属性值的方法,此时该属性变成只读属性。如果此时仍然设置属性,会抛出异常 AttributeError: can't set attribute。
- 如果报错 RecursionError: maximum recursion depth exceeded while calling a Python object,很可能是对象属性名和 @property 装饰的方法名重名了,一般会在对象属性名前加一个下划线 _ 避免重名,并且表明这是一个受保护的属性。
property参考:
【待续】
相关文章推荐
- python 3全栈开发-面向对象之绑定方法(classmethod与staticmethod的区别)、多态、封装的特性property
- Python面向对象之封装、property特性、绑定方法与非绑定方法
- Python基础(17)_面向对象程序设计(抽象类、继承原理、封装、多态,绑定方法)
- python面向对象编程之封装-绑定方法与非绑定方法
- 封装的python mysql操作ORM类
- Python实现飞机大战(封装后版本)
- caffe的python接口封装原理与解析
- python面向对象(二)之封装
- python进阶学习笔记(六)——封装中的 @property,以及私有变量的说明(转载)
- Python 封装
- [python笔记] python的封装,继承,多态
- 简化你的Python Selenium Webdriver代码:二次封装显式等待与元素定位
- python私有化、import、封装
- Linux学习笔记--Python操作mysql数据库(封装基本的增删改查)
- vue 封装组件 实现自定义双向绑定
- Python基础-动态绑定属性
- 全面解析python类的绑定方法与非绑定方法
- 第一百三十六节,JavaScript,封装库--事件绑定
- 高效开发Python扩展模块方法:用SWIG封装C/C++代码
- python 实现对excel增删改查功能的封装