Python第十一课,类的权限
时间:2023-2-27 21:26 作者:wen 分类: Python
属性私有化
为了更好的保护属性安全, 即不能随意修改, 将属性定义为私有属性, 添加一个可调用的方法去访问.
语法 : 两个下划线开头, 声明该属性为私有, 不能再累的外部被使用或直接访问.
私有化方法
私有化方法和私有化属性概念一样, 有些重要的方法, 不允许外部调用, 防止子类意外重写, 把普通的方法设置成私有化方法.
特效: 私有化方法一般是类内部调用, 子类不能继承, 外部不能调用.
单下划线, 双下划线, 头尾双下划线说明:
xxx 前面加一个下划线, 以单下划线开头的表示的是protected类型的变量, 即保护类型智能允许其本身与子类进行访问, 不能使用 from xxx import * 的方式导入.
xxx_前后两个下划线, 魔术方法, 一般是Python自有, 开发者不要创建这类型的方法
xxx 后面单下划线, 避免属性名与Python关键字冲突
# 私有属性 私有化方法 property属性
class Person:
__name: str = '' # 定义一个私有化类属性
def __init__(self):
self.__age = 30 # 私有化属性
pass
def __eat(self): # 私有化方法
print('吃东西')
pass
# def get_age(self): # 私有属性的访问
# return self.__age
# pass
#
# def set_age(self, age): # 私有属性的设置
# if 0 < age < 150: # 这个比其它语言更贴近生活
# self.__age = age
# else:
# print('年龄参数有误')
# pass
def run(self):
print('飞快的跑')
pass
# 定义一个类属性 实现通过直接访问属性的形式去访问私有的属性
# age = property(get_age, set_age)
# 通过装饰器得方法去声明
@property # 提供一个getter
def age(self):
return self.__age
@age.setter # 提供一个setter
def age(self, age):
if 0 < age < 150: # 这个比其它语言更贴近生活
self.__age = age
else:
print('年龄参数有误')
pass
p = Person()
print(p.age)
p.age = 199
print(p.age)
new
创建并返回一个实例对象, 如果new只调用了一次, 就会得到一个对象. 继承自Object的新式类才有new这一魔术方法
new是在一个对象实例化的时候所调用的第一个方法
new至少必须要有一个参数
new必须返回实例对象
new不能调用自身的new方法, 即 return cls.new(cls), 否则报错,超过最大递归深度。
class Person:
# 默认结构如下
def __new__(cls, *args, **kwargs):
print('new 方法调用')
return super().__new__(cls, *args, **kwargs)
pass
def __init__(self):
print('init 方法调用')
self.name = 'zhangsan'
print(self.name)
pass
pass
p = Person()
# 在新式类中 new 才是真正的实例化方式, 为类提供外壳制造出实例框架, 然后调用该框架内的构造方法 __init__ 进行丰满操作
单例模式
是一种常用的软件设计模式, 目的, 确保某一个类只有一个实例存在
# 参加一个单例对象
class Db:
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'): # 如果不存在就开始创建
cls._instance = super().__new__(cls, *args, **kwargs)
return cls._instance
pass
pass
db1 = Db()
print(id(db1))
db2 = Db()
print(id(db2))
输出结果:
24307720
24307720
错误与异常处理
# 语法格式
try:
'可能出现错误的代码块'
except: # 指定类型捕获异常
'出错之后执行的代码块'
else:
'没出错的代码块'
finally:
'不管有没有出错都执行的代码块'
except 在捕获错误异常的时候, 是要根据具体的错误类型来捕获
# Exception 可以捕获所有的异常
try:
li = [1, 2, 3, 4]
# print(li[10])
a = 10 / 0
pass
except Exception as msg:
# 捕获异常
print(msg)
pass
自定义异常
# 自定义异常
class MyException(Exception):
def __init__(self, length):
"""
初始化类
:param len: 长度
"""
self.length = length
pass
def __str__(self):
return "你输入的长度是:%s, 已经超过规定长度" % str(self.length)
pass
pass
def name_test():
name = input('请输入姓名:')
if len(name) > 4:
raise MyException(len(name))
else:
print(name)
pass
pass
try:
name_test()
except MyException as msg:
print(msg)
pass
动态添加属性和方法
import types # 添加方法的库
# 动态添加属性和方法
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
pass
def __str__(self):
return '{}今年{}岁了'.format(self.name, self.age)
pass
z3 = Person('zhangsan', 18)
print(z3)
z3.weight = 80 # 动态添加属性
print(z3.weight)
li4 = Person('lisi', 20)
print(li4)
li4.school = "北京大学"
print(li4.school) # 动态添加属性
def func(self):
print('{}的体重{}kg'.format(self.name, self.weight))
pass
# 动态添加方法
z3.print_info = types.MethodType(func, z3)
z3.print_info() # 调用动态方法
@classmethod
def classfun(cls):
print('类方法')
@staticmethod
def staticfun():
print('静态方法')
# 动态添加类方法
Person.class_method = classfun
Person.class_method()
# 动态添加静态方法
Person.static_method_ = staticfun
Person.static_method_()
slots属性
python 允许在定义class的时候, 定义一个特殊的slots变量, 来限制该class实例添加的属性.
只有在slots变量中的属性才能被添加, 没有在slots变量中的属性会添加失败. 可以防止其他人在调用类的时候胡乱添加属性和方法. slots属性子类不会继承, 只有在当前类中有效。
# __slots__ 属性
# 限制要添加的实例属性
# 节约内存空间
class Person:
# __slots__ = ('name','age')
def __str__(self):
return '{}---{}'.format(self.name,self.age)
pass
xw = Person()
xw.name = '小王'
xw.age = 20
# xw.sex = '男' # 不能添加
print(xw)
print(xw.__dict__) # 所有的属性都在这里存储
# 可以看到 定义了 slots 属性后, 实例不能随意创建不在slots实例属性, 同时实例当中也不再有__dict__属性了
# 在继承关系中使用 __slots__
# 子类未声明 __slots__时, 子类可以随意的添加实例属性
# 子类声明 __slots__ 时, 子类会继承父类 + 自己定义的(子类和父类的交集)
class SubPerson(Person):
__slots__ = ()
pass
ln = SubPerson()
ln.name = '男'
print(ln.name)
标签: python基础