Python——私有化和动态添加属性和方法、Property、new和slots方法、单例、异常处理(day09)

目录

一、私有化属性

二、私有化方法

三、Property属性(属性函数)

四、__new__和单例模式

五、错误与异常处理

六、自定义异常

七、动态绑定属性和方法

八、__slots__属性

九、作业

十、内置异常


一、私有化属性

 

 

# 使用私有属性的场景
# 1.把特定的一个属性隐藏起来  不想让类的外部进行直接调用
# 2.我想保护这个属性 不想让属性的值随意的改变
# 3.保护这个属性   不想让派生类【子类】去继承

class Person:
    __hobby='跳舞'  #私有的类属性
    def __init__(self):
        self.__name='李四' #加两个下划线 将此属性私有化之后  就不能再外部直接访问了,当然在类的内部是可以防蚊贴
        self.age=30
        pass
    def __str__(self):
        '''
        私有化的属性在内部可以使用 self.__name
        :return:
        '''
        return '{}的年龄是{} 爱好是{}'.format(self.__name,self.age,Person.__hobby)
    def  changeValue(self):
        Person.__hobby='唱歌'
class Student(Person):
    def printInfo(self):
        # print(self.__name)  #在此访问父类中的私有属性 可以吗?   不可以
        print(self.age)
    pass


stu=Student()
# print(stu.__name)
stu.printInfo()
stu.changeValue() #修改私有属性的值
print(stu)
# print(stu.__hobby) #实例对象访问类属性
# print(Person.__hobby) #实例对象访问类属性

# xl=Person()
# # print(xl.__name) #是通过类对象 在外部访问的 不能访问私有属性
# print(xl)

# 小结:
# 1 私有化的【实例】属性 不能再外部直接的访问  可以在类的内部随意的使用
# 2.子类不能继承父类的私有化属性【只能继承父类公共的属性和行为】
# 3. 在属性名的前面直接加‘ __’  就可以变为私有化了

二、私有化方法

三、Property属性(属性函数)

class Person(object):
    def __init__(self):
        self.__age = 18 # 定义一个私有化属性,属性名字前加连个 __ 下滑线
    # def get_age(self): # 访问私有实例属性
    #     return self.__age
    # def set_age(self,age): # 修改私有实例属性
    #     if age < 0:
    #         print('年龄不能小于0')
    #     else:
    #         self.__age=age
    #         pass
    #     pass
    # 定义一个类属性  实现通过直接访问属性的形式去访问私有的属性
    # age=property(get_age,set_age)
    # 实现方式2  通过装饰器的方式去声明
    @property  #用装饰器修饰 添加属性标志  提供一个getter方法
    def age(self):
        return self.__age
    @age.setter   #提供一个setter方法
    def age(self,parms):
        if parms < 0:
            print('年龄不能小于0')
        else:
            self.__age=parms
            pass
        pass


    pass
p1=Person()
print(p1.age)
p1.age=30
print(p1.age)
# p1.get_age()
# p1.set_age()

四、__new__和单例模式

(1)__new__

 

 new就是开辟对象在内存的地址

class Animal:
    def __init__(self):
        self.color='红色'
        pass
    #在python当中, 如果不重写 __new__ 默认结构如下
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls,*args, **kwargs)
        # return object.__new__(cls, *args, **kwargs)
    pass

tigger=Animal() #实例化的过程会自动调用__new__去创建实例
# 在新式类中 __new__  才是真正的实例化的方法,为类提供外壳制造出实例框架,然后调用该框架内的构造方法__init__ 进行丰满操作
# 比喻建房子 __new__   方法负责开发地皮 打地基 并将原料存放在工地,而__init__ 负责从工地取材料建造出地皮开发图纸规定的大楼,
# 负责细节设计、建造 最终完成

(2)单例模式

# 单例模式  是一种常用的软件设计模式 目的:确保某一个类只有一个实例存在
# 如果希望在真个系统中 某个类只能出现一个实例的时候,那么这个单例对象就满足要求

# 创建一个单例对象 基于__new__去实现的【推荐的一种】

class DataBaseClass(object):
    def __new__(cls, *args, **kwargs):
        # cls._instance=cls.__new__(cls)  不能使用自身的new方法
            # 容易造成一个深度递归,应该调用父类的new方法
        if not hasattr(cls,'_instance'):  #如果不存在就开始创建
            cls._instance=super().__new__(cls,*args, **kwargs)
        return cls._instance
    pass

class DBoptSingle(DataBaseClass):
    pass

db1=DBoptSingle()
print(id(db1))
db2=DBoptSingle()
print(id(db2))
db3=DBoptSingle()
print(id(db3))

cls._instance:给类对象赋一个属性,super().__new__(cls,*args, **kwargs)后面的*args, **kwargs传不传无所谓。

五、错误与异常处理

异常	        导致的错误
AssertionError	当assert语句失败时引发。
AttributeError	当属性分配或引用失败时引发。
EOFError	当input()函数达到文件结束条件时引发。
FloatingPointError	当浮点运算失败时引发。
GeneratorExit	调用生成器的close()方法时引发。
ImportError	找不到导入的模块时引发。
IndexError	当序列的索引超出范围时引发。
KeyError	在字典中找不到键时引发。
KeyboardInterrupt	当用户按下中断键(Ctrl+c或delete)时引发。
MemoryError	当操作耗尽内存时引发。
NameError	在局部或全局范围内找不到变量时引发。
NotImplementedError	由抽象方法提出。
OSError	当系统操作导致系统相关错误时引发。
OverflowError	当算术运算的结果太大而无法表示时引发。
ReferenceError	使用弱引用代理访问垃圾收集的引用时引发。
RuntimeError	当错误不属于任何其他类别时引发。
StopIteration	函数引发,以指示迭代器不再返回任何项。
SyntaxError	遇到语法错误时由解析器引发。
IndentationError	当缩进不正确时引发。
TabError	当缩进由不一致的制表符和空格组成时引发。
SystemError	当解释器检测到内部错误时引发。
SystemExit	由sys.exit()函数引发。
TypeError	将函数或操作应用于类型不正确的对象时引发。
UnboundLocalError	当在函数或方法中引用局部变量,但没有将值绑定到该变量时引发。
UnicodeError	当发生与unicode相关的编码或解码错误时引发。
UnicodeEncodeError	当编码过程中发生与unicode相关的错误时引发。
UnicodeDecodeError	当解码过程中出现与unicode相关的错误时引发。
UnicodeTranslateError	翻译过程中发生与unicode相关的错误时引发。
ValueError	当函数得到类型正确但值不正确的参数时引发。
ZeroDivisionError	当除法或模运算的第二个操作数为零时引发。

 

 

 万能捕获类型:Exception

except Exception as result:
    print(result)
# import Exception
# except 在捕获错误异常的时候  只要根据具体的错误类型来捕获的
# 用一个块 可以捕获多个不同类型的异常
# Exception 可以捕获所有的异常  当对出现的问题或者错误不确定的情况下  可以使用Exception
# print(dir(Exception))
try:
    # print(b) #捕获逻辑的代码
    li=[1,2,34]
    print(li[10])  #通过下标去访问列表
    # a=10/0
    pass
# except  NameError as msg:
#     # 捕获到的错误 才会在这里执行
#     print(msg)
#     pass
# except IndexError as msg:
#     print(msg)
#     pass
# except ZeroDivisionError as msg:
#     print(msg)
#     pass
except Exception as result:
    # print(result)
    # 在此尽量的去处理捕获到的错误
    pass
# print('初次接触异常处理')
# print('HAHAHAHHAHA')

def A(s):
    return 10/int(s)
    pass
def B(s):
    return A(s)*2
def main():
    # B(0)
    try:
        B('0')
        pass
    except Exception as msg:
        print(msg)
        pass
    pass

# main()
# 不需要在每个可能出错的地方去捕获,只要在合适的层次去捕获错误就可以了 这样的话 就大大减少我们写try---except的麻烦
# 异常的抛出机制
#如果在运行时发生异常  解释器会查找相应的异常捕获类型
#如果在当前函数里面没有找到的话  它会将异常传递给上层的调用函数,看能否处理
# 如果在最外层 没有找到的话,解释器就会退出 程序down哦

# try-except-else

# try:
#     print('我是没有错误产生的')
#     pass
# except SyntaxError as msg:
#     print(msg)
# except Exception as msg:
#     print('error',msg)
# else:
#     print('当Try里面的代码 没有出现异常的情况下 我才会执行')
#     pass

# try-except-finally
try:
    int('34')
    open('aaaa.txt')
except Exception as msg:
    print(msg)
    pass
finally:
    print('释放文件的资源、数据库连接是资源等等')
    print('不管有没有出错都执行的代码块')

六、自定义异常

class ToolongMyException(Exception):
    def __init__(self,leng):
        '''

        :param leng: 长度
        '''
        self.len=leng
        pass
    def __str__(self):
        return '您输入姓名数据长度是'+str(self.len)+'超过长度了..'
    pass

def name_Test():
    name=input('请输入姓名.....')
    try:
        if  len(name)>5:
            raise ToolongMyException(len(name))
        else:
            print(name)
            pass
        pass
    except ToolongMyException as result:
        print(result)
        pass
    finally:
        print('执行完毕了....')

name_Test()

七、动态绑定属性和方法

zyh.printInfo=types.MethodType(dymicMethod,zyh)中:

MethodType(a, b):a是被绑定的方法,b是被绑定的对象

import types  #添加方法的库

def dymicMethod(self):
    print('{}的体重是:{}kg 在 {} 读大学'.format(self.name,self.weight,Student.shcool))
    pass
@classmethod
def classTest(cls):
    print('这是一个类方法')
    pass

@staticmethod
def staticMethodTest():
    print('这是一个静态方法')
    pass

class Student:
    def __init__(self,name,age):
        self.name=name
        self.age=age
    pass
    def __str__(self):
        return '{}今天{}岁了'.format(self.name,self.age)
    pass

print('绑定类方法')
Student.TestMethod=classTest
# Student.TestMethod()

Student.staticMethodTest=staticMethodTest
Student.staticMethodTest()


print('---------------绑定类方法执行结束----------------------')

zyh=Student('张艳华',20)
zyh.weight=50 #动态添加
zyh.printInfo=types.MethodType(dymicMethod,zyh) #动态的绑定方法

zyh.TestMethod()
print('-------------实例对象调用 动态绑定类方法-----------------------')
# print(zyh)
# print(zyh.weight)
print('-------------另外一个实例对象  张明--------------------------')
zm=Student('张名',20)
zm.weight=80 #动态添加
print(zm)

zm.printInfo=types.MethodType(dymicMethod,zm) #动态的绑定方法
# print(zm.weight)
print('-------------给类对象添加属性--------------------------')
Student.shcool='北京邮电大学' #动态添加类属性
print(zm.shcool)
print('-------------执行动态调用实例方法--------------------------')
zyh.printInfo() #调用动态绑定的方法
zm.printInfo() # zm会报错,因为zm没有weight

八、__slots__属性

 

 __slots__:性能好,比直接存储到__dict__快

# 作用
# 限制要添加的实例属性
# 节约内存空间
class Student(object):
    __slots__ = ('name','age','score')
    def __str__(self):
        return '{}....{}'.format(self.name,self.age)
    pass
xw=Student()
xw.name='小王'
xw.age=20
xw.score=96 # 没有在范围内 所以报错
# print(xw.__dict__) #所有可以用的属性都在这里存储  不足的地方就是占用的内存空间大
# 可以看到 在定义了 slots变量之后 student类的实例已经不能随意创建不在 __slots__定义的属性了
# 同时还可以看到实例当中也不在有__dict__
# print(xw)

# 在继承关系当中的使用  __slots__
# 子类未声明  __slots__时,那么是不会继承父类的__slots__,此时子类是可以随意的属性赋值的
# 子类声明 了__slots__时,继承父类的__slots__,也就是子类__slots__的范围是为
# 其自身+父类的__slots__
class subStudent(Student):
    __slots__ = ('gender','pro')
    pass
ln=subStudent()
ln.gender='男'
ln.pro='计算机信息管理'
print(ln.gender,ln.pro)

九、作业

以下代码中,xw()是以函数的形式调用,而__call__方法也是以函数形式调用

# 1、Python中new方法作用是什么?

# 用来创建实例对象的,只有继承了object的话 才能有这个方法,python3版本默认继承

# 2、什么是单例模式?单例模式适用于什么场景?
# 回答:

#  要求一个类有且只有一个实例,并且提供了一个全局的访问点
#  场景:日志插入logger的操作,网站计数器,权限验证模块,window资源管理器、系统回收站,数据库连接池

# 3、私有化方法与私有化属性在子类中能否继承?
# 不能的

# 4、在Python中什么是异常?
#  异常就是程序在执行的过程中发生的错误
# 5、Python中是如何处理异常的。
#  分别根据异常的类型去处理
# 6、Python中异常处理语句的一般格式,可以使用伪代码的形式描述。

# try:
#     # 正常操作
# except:
#     # ......
# else:
#     # .....
# finally:
#     # .....
# 7、__slots__属性的作用
# 限制属性的随意输入
# 节省内存空间  __dict__
# 8、私有化属性的作用?
# 保护数据,封装性的体现
# 9、在类外面是否能修改私有属性。
# 不可以直接修改的 通过方法去实现  还可以借助属性函数 property去实现
# 10、如果一个类中,只有指定的属性或者方法能被外部修改。那么该如何限制外部修改。
#  对属性进行私有化的设定

# 1、编写一段代码以完成下面的要求
# 定义一个Person类,类中要有初始化方法,方法中要有人的姓名,年龄两个私有属性.
# 提供获取用户信息的函数.
# 提供获取私有属性的方法.
# 提供可以设置私有属性的方法.
# 设置年龄的范围在(0-120)的方法,如果不在这个范围,不能设置成功.
class Person:
    def __init__(self,n,a):
        '''

        :param n:
        :param a:
        '''
        self.__name=n
        self.__age=a
        pass
    def __str__(self):
        return '{}的年龄是:{}'.format(self.__name,self.__age)
    def getAgeInfo(self):
        return self.__age
    def setAge(self,age):
        if age>0 and age<120:
            self.__age=age
            pass
        else:
            print('您输入的数据不合法')
    def getNameInfo(self):
        return self.__name
    def setName(self,name):
        self.__name=name

# 2、请写一个单例模式
# 省略
# 3、创建一个类,并定义两个私有化属性,提供一个获取属性的方法,和设置属性的方法。利用property 属性给调用者提供属性方式的调用获取和设置私有属性方法的方式。
class Student:
    def __init__(self):
        self.__name='张三'
        self.__score=90
        pass
    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self,name):
        self.__name=name
        pass

    @property
    def score(self):
        return self.__score

    @score.setter
    def score(self, score):
        self.__score = score
        pass
    def __str__(self):
        return self.__name
    def __call__(self, *args, **kwargs):
        # print(self.__name+'的得分是:'+(str)self.__score)
        print('{}的得分是:{}'.format(self.__name,self.__score))
        pass
    pass

# xw=Student()
# xw() #将实例对象以函数的形式去调用
# xw.name='李四'
# xw.score=98
# xw()
# print(xw)
# 4、创建一个Animal类,实例化一个cat对象,请给cat对象动态绑定一个run方法,给类绑定一个类属性colour,给类绑定一个类方法打印字符串'ok'。
import types
def run(self):
    print('小猫飞快的跑...')
    pass
@classmethod
def info(cls):
    print('ok')
class Animal:
    pass

Animal.colour='黑色'#绑定类属性
Animal.info=info
cat=Animal()
cat.run=types.MethodType(run,cat) #动态绑定
cat.run()
print(cat.colour)
Animal.info()

十、内置异常

异常        导致的错误
AssertionError当assert语句失败时引发。
AttributeError当属性分配或引用失败时引发。
EOFError当input()函数达到文件结束条件时引发。
FloatingPointError当浮点运算失败时引发。
GeneratorExit调用生成器的close()方法时引发。
ImportError找不到导入的模块时引发。
IndexError当序列的索引超出范围时引发。
KeyError在字典中找不到键时引发。
KeyboardInterrupt当用户按下中断键(Ctrl+c或delete)时引发。
MemoryError当操作耗尽内存时引发。
NameError在局部或全局范围内找不到变量时引发。
NotImplementedError由抽象方法提出。
OSError当系统操作导致系统相关错误时引发。
OverflowError当算术运算的结果太大而无法表示时引发。
ReferenceError使用弱引用代理访问垃圾收集的引用时引发。
RuntimeError当错误不属于任何其他类别时引发。
StopIteration函数引发,以指示迭代器不再返回任何项。
SyntaxError遇到语法错误时由解析器引发。
IndentationError当缩进不正确时引发。
TabError当缩进由不一致的制表符和空格组成时引发。
SystemError当解释器检测到内部错误时引发。
SystemExit由sys.exit()函数引发。
TypeError将函数或操作应用于类型不正确的对象时引发。
UnboundLocalError当在函数或方法中引用局部变量,但没有将值绑定到该变量时引发。
UnicodeError当发生与unicode相关的编码或解码错误时引发。
UnicodeEncodeError当编码过程中发生与unicode相关的错误时引发。
UnicodeDecodeError当解码过程中出现与unicode相关的错误时引发。
UnicodeTranslateError翻译过程中发生与unicode相关的错误时引发。
ValueError当函数得到类型正确但值不正确的参数时引发。
ZeroDivisionError当除法或模运算的第二个操作数为零时引发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清园暖歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值