• python之面向对象的成员,方法,属性,异常处理


    一、类的私有成员

    1. 类中的私有成员是什么?

    私有:只有满足一部分条件的才能使用

    • 私有类的属性
    • 私有对象的属性
    • 私有方法

    正常状态

    class B:
        school_name = '老男孩教育'
        def __init__(self,name, sex, age):
            self.name = name
            self.sex = sex
            self.age = age
    
    class A(B): # A的父类是B,这个时候意味着A的实例化对象就可以使用B类中的所有属性或者方法
    
        class_name = 'python23'
    
        def func(self):
            print(self.class_name)
            print(self.name)
    obj = A() # 实例化一个对象A
    print(obj.class_name)
    obj.func()# 通过实例化对象来执行A类中的方法
    print(obj.school_name)
    
    obj = A('alex', '男', 123)
    obj.func() #调用A类中的func方法
    print(obj.class_name) # 调用A类中的class_name
    print(obj.school_name) # 调用B类中的school_name
    

    私有成员有哪些

    class A:
    
        company_name = '老男孩教育'  # 静态变量(静态字段)
        __iphone = '1353333xxxx'  # 私有静态变量(私有静态字段)
    
    
        def __init__(self,name,age): #特殊方法
    
            self.name = name  #对象属性(普通字段)
            self.__age = age  # 私有对象属性(私有普通字段)
    
        def func1(self):  # 普通方法
            pass
    
        def __func(self): #私有方法
            print(666)
    
    
        @classmethod  # 类方法
        def class_func(cls):
            """ 定义类方法,至少有一个cls参数 """
            print('类方法')
    
        @staticmethod  #静态方法
        def static_func():
            """ 定义静态方法 ,无默认参数"""
            print('静态方法')
    
        @property  # 属性
        def prop(self):
            pass
    

    2. 设置类的私有静态属性(***)

    格式

    __girlnum = '1个'

    • 对象在类的外部不能访问,类在外部也不能访问
    • 只能在类的内部可以访问

    内部访问方法:封装到方法内部,然后obj.func() #良心教育

    类的私有成员有什么用?

    如果想设定一些私有的或者是不想让类外面用到的,密码,加密方式等,设置成私有成员即可

    例题

    # 私有静态属性
    class  B:
    	school_name = 'OldBoy'
    
    class A(B):
    	class_name = 'python23'
    	
    	_girlnum = '1个' # 我就是私有属性
    
    	
    	def func(self):
    		# print(self.class_name)
    		print(self.__girlnum)
    obj = A() 实例化
    print(obj.__girlnum) # 对象在类的外部不能访问,类在外部也不能访问print(A.__girlnum),这种就是私有属性
    print(obj.func()) # 在类的内部可以访问
    从类的外部调用
    print(obj.calss_name)
    从类的内容部调用
    obj.func()
    
    prin(obj.school_name) 对于类的共有静态属性,类的外部,累的内容部,派生类都可调用
    
    

    3. 设置对象的私有属性

    格式:

    self.__age = age # 定义方法,这就变成了私有成员了

    obj.func()调用方法

    • 在类的外部是无法访问的
    • 在类的内部可以使用
    class  B:
    
    	def __init__(self, name, age)
    			self.name = name
    			self.__age = age # 这就变成了私有成员了
    	def func(self):
    			print(self.__age)
    			
    print(obj.__age)#在类的外部是无法访问的
    obj.func()# 在类的内部可以使用
    
    
    #派生类
    既想用子类也想用父类用super
    子类打印父类属性,派生类中也不能访问
    

    4. 私有成员的拓展

    私有成员除了类的内部真的访问不到吗?

    class A:
    		__girl_num = '1个'
    
    print(A._dict_)
    # 输出结果
    '_A__girlnum'
    
    print(A.__A_girlnum) # 这样是可以访问的,千万不要去访问
    

    python中所有的私有成员,就是在私有成员前面加上__类名而已.所以是可以访问的

    二、类的方法和静态方法

    类方法 @classmethod用途

    • 把一个对象绑定的方法修改成一个类方法
    • 在方法中任然可以引用类中的静态变量
    • 可以不用实例化对象,就直接用类名在外部调用这个方法

    类方法怎么用?(***)

    定义方法: @classmethod cls

    调用方法: A.a_func() 通过用类名和对象名obj.a_func()调用

    class A:
    		num = 1
    	
    	def func(self):
    		print('实例方法')
    	
    	# 以下就是类方法
    	@classmethod 
    	def a_func(cls):
    			print(f'cls-->{cls}')
    			print('这就是类方法')
    
    # 类方法的调用方法
    obj = A()
    A.func(obj) # self会得到obj这个对象
    A.a_func()# 进行调用
    

    类方法什么时候用?

    • 定义一个方法,默认传self单这个self没有被使用
    • 并且你在这个方法里用到了当前的类名,或者你准备使用这个类的内存空间中的名字的时候
    • 就是你想在实例化之前修改一个类的属性,就可以用这个

    例题:统计学生的个数

    class Student:
        count = 0
        def __init__(self, name):
            self.name = name
            self.count1()
    
        @classmethod
        def count1(cls):
            cls.count += 1
    
        @classmethod
        def print1(cls):
            return cls.count
    
    ly = Student('李烨')
    sq = Student('扫强')
    sq1 = Student('扫强')
    sq2 = Student('扫强')
    sq3 = Student('扫强')
    sq4 = Student('扫强')
    
    print(f'学生共计: {Student.print1()}个')
    
    # 输出结果
    学生共计: 6个
    
    

    静态方法(***)

    用途

    不依赖于类,也不依赖于对象,他就是一个普通的函数放置于类中是结构更加清晰与合理.

    怎么用?

    定义一个静态方法:@staticmethod

    调用一个静态方法:A.static_func()

    例题

    class A:
    		def func(self):
    				print(111)
    		@classmethod
    		def a_func(cls):
    				print(cls)
    		@staticmethod
    		def static_func(a,b,c): # 也可以传参,就当做一个函数用就行
    				print('静态方法')
    		
    A.static_func() # 类调用静态方法
    
    obj = A()
    obj.static_func(1,2,3)
    
    为什么这种函数不写到类的外面?
    也用不着类中的内容,但是为了划分,还是要放置于类中,显得与结构更加清晰与合理
    
    切记在函数中要用return的方法返回值进行打印.
    
    

    三、属性(伪装)

    用途

    将方法伪装成一个属性,这样看起来更合理

    operty是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

    有问题的例题

    class Bmi:
    
        def __init__(self, hight, shoot):
            self.hight = hight
            self.shoot = shoot
    
        def bmi(self):
            BIM = self.shoot/self.hight**2
            return BIM
    
    obj = Bmi(1.75,67)
    print(obj.bmi())
    
    # 输出结果
    21.877551020408163
    

    属性怎么用?

    伪装一个属性: @property

    调用一个属性: obj.bmi 直接执行不用加括号,从执行方法看起来像一个属性,而看起来不是一个方法

    将上段代码进行伪装,我们要让bmi伪装成一个属性

    class Bmi:
    
        def __init__(self, hight, shoot):
            self.hight = hight
            self.shoot = shoot
    		
    		@property
        def bmi(self):
            BIM = self.shoot/self.hight**2
            return BIM
    
    obj = Bmi(1.75,67)
    print(obj.bmi) #不用加括号了
    # 输出结果
    21.877551020408163
    

    伪装属性有三种@property @aaa.setter @aaa.delter

    1. 先伪装 obj.bmi()变成obj.bmi @property 
     def aaa(self): 
     print('get的时候执行我')
    2. @aaa.setter  --> def aaa(self,v): 
     print('修改的时候执行我') --> obj.aa = '太白' # 结果: 太白 aaa三者必须是一致的
    3. @aaa.delter --> def aaa(self): 
     print('删除的时候执行我') del Bmi.bmi
    

    注意事项:

    • 设置属性,你的对象属性一定不能出现同名的属性
    • setter,deleter这两个装饰器装饰的函数不能使用return

    函数与面向对象的区别

    四、isinstance/issubclass/type

    isinstance(a,b): 判断a是由b类(b的派生类)实例化的对象.

    判断的是类与对象的关系

    class A:
    		pass
    	
    class B(A):
    		pass
    
    obj = B()
    print(isinstance(obj,B))
    print(isinstance(obj,A))
    # 输出结果
    True
    True
    
    issubclass(M,N)判断M类是N类的子孙
    class A:
    		pass
    	
    class B(A):
    		pass
    
    class C(B):
    print(isinstance(C,B))
    print(isinstance(C,A))
    # 输出结果
    True
    True
    

    type是什么?

    type 是一个原类, 用来判断一个数据类型是由哪个类实例化的对象,python中一切皆对象,一个类也是一个对象,那么这个类对象肯定是由类实例化出来的.

    python中你创建的所有类,以及大部分list str 等等这些类都是从type原类实例化得来的

    python中继承object类都是新式类.

    object也是由type原类实例化得来的

    五、异常处理

    什么叫异常

    你的程序出现中断,飘红,致使你的整个项目中断了.

    错误类型

    语法错误

    ​ 自己去避免,就不应该出现在你的代码中

    逻辑错误

    l1 = [1,2,3]
    print(l1[4]) #超过了取值范围
    

    异常错误处理

    • 用if进行异常处理:缺点,嵌套太多,太复杂,只能进行简单的异常处理
    • 用try简单尝试一下

    try(***)

    从上到下捕捉错误信息,然后进行引流,也有分流的作用

    单分支错误就是设置一个except和多分支就是设置多个except

    及时解决异常,避免程序中断

    status_dic = {
        1: 111,
        2: 333,
        3: 444,
    
    }
    while 1:
        try:
    
            num = input('请输入序号')
            int(num)
            print(status_dic[int(num)])
    
        except KeyError as e:
            print('选项超出范围,重新输入')
        except ValueError as e:
            print('请输入数字')
    
    

    万能异常

    status_dic = {
        1: 111,
        2: 333,
        3: 444,
    
    }
    while 1:
        try:
    
            num = input('请输入序号')
            int(num)
            print(status_dic[int(num)])
    
        except Exception as e:
        		print(e)
    print(111)
    

    什么时候用万能异常,什么时候用多分支?

    • 如果你只是想把这个异常处理掉,让程序继续执行,这个时候用万能异常
    • 如果出现了异常,你是想根据不同的异常执行不同的逻辑流程,你要采取多分支

    万能+多分支

    status_dic = {
        1: 111,
        2: 333,
        3: 444,
    
    }
    while 1:
        try:
    
            num = input('请输入序号')
            int(num)
            print(status_dic[int(num)])
    
        except KeyError as e:
            print('选项超出范围,重新输入')
        except ValueError as e:
            print('请输入数字')
         except Exception:
    				pass
    

    异常处理的其他成员

    status_dic = {
        1: 111,
        2: 333,
        3: 444,
    
    }
    while 1:
        try:
    
            num = input('请输入序号')
            int(num)
            print(status_dic[int(num)])
    
        except KeyError as e:
            print('选项超出范围,重新输入')
        except Exception:
    				pass
    
    # else
    status_dic = {
        1: 111,
        2: 333,
        3: 444,
    
    }
    while 1:
        try:
    
            num = input('请输入序号')
            int(num)
            print(status_dic[int(num)])
    
        except KeyError as e:
            print('选项超出范围,重新输入')
        except Exception:
    				pass
    		else: # 不出现异常执行,如果出现异常就不执行
    				print(666)
    
    
    # finally
    status_dic = {
        1: 111,
        2: 333,
        3: 444,
    
    }
    while 1:
        try:
    
            num = input('请输入序号')
            int(num)
            print(status_dic[int(num)])
    
        except KeyError as e:
            print('选项超出范围,重新输入')
        except Exception:
    				pass
    		finally: # 在异常发生之前执行finally
    				print('执行finally')
    
    

    使用场景:

    • 文件操作

    目的是在报错之前,关闭文件句柄

    方法:

    try:
    
    	xxx
    
    	xxx
    
    finally:
    	  print('哈哈哈哈')
        f.close()
    
    f = open('register', mode='w')
    f.write('fdjsaklfd')
    f.write('fdjsaklfd')
    f.write('fdjsaklfd')
    l1 = [1,2,3]
    print(l1[1000])
    f.write('fdjsaklffjdsklaf')
    
    f.close()
    
    try:
        f = open('register', mode='w')
        f.write('fdjsaklfd')
        f.write('fdjsaklfd')
        f.write('fdjsaklfd')
        l1 = [1, 2, 3]
        print(111)
        print(l1[1000])
        f.write('fdjsaklffjdsklaf')
    finally:
        print('哈哈哈哈')
        f.close()
    
    
    • 连接数据库引擎
    
    

    在函数中的finally

    def func():
    		try:
    				a = 1
    				b = 2
    				return a + b
    		finally:
    				print(666)
    func()
    				
    

    主动抛出异常

    Raise Exception('sdfasdf')

    断言

    assert 条件  # 源码上assert.
    assert 1 == 2
    print(11)
    print(22)
    print(33)
    

    自定义异常

    TypeError
    
    class Connection(BaseException):
    
        def __init__(self,msg):
            self.msg = msg
    
    
    raise Connection('触发了连接异常')
    
    
    # 异常处理总结:
    # 异常处理不能经常使用:异常处理耗费性能.有些错误是需要进行分流使用.代码的可读性变差.
    # 关键节点使用.
    
  • 相关阅读:
    VLC在web系统中应用(xvlcplugin 即如何把VLC嵌入HTML中)
    mysql in 排序
    EditPlus v3.31 注册码
    UTF8编码判断
    zend framework 获取邮箱内容 编码转换 quoted_printable_decode | base64_decode
    String path = request.getContextPath(....拼装当前网页的相对路径
    【转】input中id和name的区别
    JSON基础知识
    【转】 jdbc.properties
    JSP页面传值乱码过滤
  • 原文地址:https://www.cnblogs.com/zanao/p/11227568.html
Copyright © 2020-2023  润新知