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 \n def aaa(self): \n print('get的时候执行我')
2. @aaa.setter  --> def aaa(self,v): \n print('修改的时候执行我') --> obj.aa = '太白' # 结果: 太白 aaa三者必须是一致的
3. @aaa.delter --> def aaa(self): \n 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('触发了连接异常')

# 异常处理总结:
# 异常处理不能经常使用:异常处理耗费性能.有些错误是需要进行分流使用.代码的可读性变差.
# 关键节点使用.
posted @ 2019-07-22 18:21  爱咋闹  阅读(298)  评论(0编辑  收藏  举报