python中属性的权限分为两种
1.公开的
没有任何限制 谁都能访问
2.私有的(封装)
只有当前类本身能够访问
一般默认为公共的
4. 封装属性(提高数据的安全性)
class Student:
def __init__(self,name,age,gender,id_card):
self.name = name
self.age = age
self.gender = gender
self.__id_card = id_card
# 访问被封装的属性 称之为访问器
def get_id_card(self,pwd):
# 可以在这里添加额外的任何逻辑代码 来限制外部的访问
# 在类的内部 可以访问
if pwd =="123":
return self.__id_card
raise Exception("密码错误!")
# 修改被封装的属性 称之为设置器
def set_id_card(self,new_id):
# 身份证必须是字符串类型
# 长度必须是18位
if isinstance(new_id,str) and len(new_id) == 18:
self.__id_card = new_id
else:
raise Exception("身份证号码 必须是字符串 且长度必须为18!")
# 注意:1)访问被封装的属性对的函数 称之为访问器 2)修改被封装的属性的函数 称之为设置器 3)可分别在访问器和设置器中添加逻辑来对外界进行限制
5.封装方法(隔离复杂度)
class ATM:
def withdraw(self):
# 输入账号和密码
self.__user_auth()
# 显示余额 输入取款金额
self.__input_money()
# 保存记录
self.__save_record()
def __user_auth(self):
print("请输入账号密码....")
def __input_money(self):
print("余额为100000000,请输入取款金额!")
def __save_record(self):
print("记录流水....")
6.封装原理
python是通过 变形的方式来实现的封装
如何变形 在名称带有双下划线开头的变量名字前添加_类名 如_Person__id_card
当然通过变形后的名字可以直接访问被隐藏的属性 但通过不应该这么做
变形仅在类的定义阶段发生一次 后续再添加的带有双下划线的任何属性都不会变形 就是普通属性
7.
Property
作用: 将一个方法伪装成普通属性
为什么用 property 希望将访问私有属性和普通属性的方式变得一致
与property相关的 两个装饰器
setter
用点语法 给属性赋值时触发
deleter
用点语法删除属性时触发
总结:将访问,设置,删除被封装的属性的函数伪装成普通属性,访问方式和普通属性一致,将这三个函数名改成和被封装属性的参数名一致,其他不变
class Teacher:
def __init__(self,name,age,salary):
self.name = name
self.age = age
self.__salary = salary
@property # getter # 用于访问私有属性的值 也可以访问普通属性
def salary(self):
return self.__salary
@salary.setter # 用来设置私有属性的值 也可以设置普通属性
def salary(self,new_salary):
self.__salary = new_salary
@salary.deleter # 用来设置私有属性的值 也可以删除普通属性
def salary(self):
# print("can not delete salary!")
del self.__dict__["_Teacher__salary"]
class Person:
def __init__(self,name,height,weight):
self.name = name
self.height = height
self.weight = weight
# self.BMI = weight / (height ** 2)
@property
def BMI(self):
return self.weight / (self.height ** 2)
@BMI.setter
def BMI(self,new_BMI):
print("BMI 不支持自定义.....")
p = Person("egon",1.7,80)
类中的__str__
该方法在object中有定义 默认行为 返回对象类型以及地址 <__main__.Person object at 0x0000016F450C7390>
在将对象转为字符串时执行
注意:返回值必须为字符串类型
子类可以覆盖该方法来完成 对打印内容的自定义
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
# 将对象转换为字符串时执行r
def __str__(self):
print("str run")
return "my name is %s , age is %s" % (self.name,self.age)
p = Person("rose",20)
# print(p) #在打印前都会现将要打印的内容转为字符串 通过调用__str__函数
# str(p)
print(p)
__del__
当对象被删除前会自动调用 该方法
声明时候会删除对象?
1.程序运行结束 解释器退出 将自动删除所有数据
2.手动调用del 时也会删除对象
注意:该函数不是用来删除对象的
使用场景
当你的对象在创建时,开启了不属于解释器的资源 例如打开了一个文件
必须保证当对象被删除时 同时关闭额外的资源 如文件
也称之为析构函数 构造 的反义词
构造 指的是从无到有
析构 值从有到无
简单的说就对象所有数据全部删除
总结:__del__该函数 用于 在对象删除前做一些清理操作
类中的__str__
该方法在object中有定义 默认行为 返回对象类型以及地址 <__main__.Person object at 0x0000016F450C7390>
在将对象转为字符串时执行
注意:返回值必须为字符串类型
子类可以覆盖该方法来完成 对打印内容的自定义
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
# 将对象转换为字符串时执行r
def __str__(self):
print("str run")
return "my name is %s , age is %s" % (self.name,self.age)
p = Person("rose",20)
# print(p) #在打印前都会现将要打印的内容转为字符串 通过调用__str__函数
# str(p)
print(p)
hasattr 判断是否存在某个属性
getattr 获取某个属性的值
setattr 新增或修改某个属性
delattr 删除某个属性
直接写import 称之为静态导入 建立在一个基础时 提前已经知道有这个模块
动态导入 指的时 在需要的任何时候 通过指定字符串类型包名称来导入需要的模块
import importlib
m_name = input("请输入要导入的模块名称:")
mk = importlib.import_module(m_name)
print(mk)