python基础---面向对象高级

简介:

面向对象高级


isinstance(obj,cls)

检查obj是否是类 cls 的对象

1
2
3
4
5
6
7
8
class  Foo( object ):
     pass
 
obj  =  Foo()
 
print ( isinstance (obj, Foo)) 
输出:
True


issubclass(sub,super)

检查sub类是否是 super 类的派生类

1
2
3
4
5
6
7
class  Foo( object ):
     pass
 
class  Bar(Foo):
     pass
 
print ( issubclass (Bar, Foo))

 

b.反射

主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)

python面向对象中的反射:通过字符串反射到真实的属性上

面向对象中类中属性的两种调用方法:

1.   类名.属性

2.类名.__dict__[‘属性名’] #通过字符串的形式

1
2
3
4
5
6
7
8
9
10
class  Foo:
     x = 1
     def  __init__( self ,name):
         self .name = name
 
     def  f1( self ):
         print ( 'from f1' )
 
 
print (Foo.x)    #方法1Foo.__dict__['x']      #方法2

 

实现自省的函数,通过操作字符串的方式映射到属性(适用于类和对象,在python中一切皆对象,类本身也是一个对象)

hasattr(obj,’name’)     判断obj中有没有一个name字符串对应的方法或属性

setattr(x,’y’,’v’)     设置函数,x对象名,y属性,v

getattr(x,’y’)         取值函数,x对象名,y属性

delattr(x,’y’)         删除函数,x对象名,y属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class  Ftpserver:
     def  __init__( self ,host,port):
         self .host = host
         self .port = port
 
     def  run( self ):
         while  True :
             cmd = input ( '>>: ' ).strip()
             if  not  cmd: continue     # 判断输入是否为空
             if  hasattr ( self ,cmd):    # 判断类中是否存在此方法
                 func = getattr ( self ,cmd)    # 取出该方法的值并赋值给func
                 func()           
     def  get( self ):
         print ( 'get func' )
 
     def  put( self ):
         print ( 'put func' )

 

反射的好处:

1.实现可插拔机制:

可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能(首先使用hasattr进行判断是否存在此方法,存在则执行,不存在则跳过)

2.动态导入模块(基于反射当前模块成员)

 

c.item系列

__setitem__      设置函数

__getitem__      取值函数

__delitem__      删除函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class  Foo:
     def  __getitem__( self , item):
         print ( '=====>get' )
         return  self .__dict__[item]
 
     def  __setitem__( self , key, value):
         print ( '==============>set' )
         self .__dict__[key] = value
         # setattr(self,key,value)
 
     def  __delitem__( self , key):
         print ( '============>del' )
         self .__dict__.pop(key)
 
 
f = Foo()
f[ 'x' ] = 123123123123     # 通过f[]的方式对对象进行操作时会调用item方法
print (f[ 'x' ])
del  f[ 'x'
输出:
= = = = = = = = = = = = = = > set
= = = = = >get
123123123123
= = = = = = = = = = = = > del


d.打印对象信息__str__

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class  People:
     def  __init__( self ,name,age,sex):
         self .name = name
         self .age = age
         self .sex = sex
 
     def  __str__( self ):                 #在对象被打印时触发执行
         return  '<name:%s age:%s sex:%s>'  % ( self .name, self .age, self .sex)
 
p1 = People( 'egon' , 18 , 'male' )
p2 = People( 'alex' , 38 , 'male' )
 
 
print (p1)
print (p2)

 

e.析构方法__del__

当对象在内存中被释放时,自动触发执行

注:如果产生的对象仅仅只是python程序级别的(用户级),那么无需定义__del__,如果产生的对象的同时还会向操作系统发起系统调用,即一个对象有用户级与内核级两种资源,比如(打开一个文件,创建一个数据库链接),则必须在清除对象的同时回收系统资源,这就用到了__del__

典型的应用场景:

创建数据库类,用该类实例化出数据库链接对象,对象本身是存放于用户空间内存中,而链接则是由操作系统管理的,存放于内核空间内存中,当程序结束时,python只会回收自己的内存空间,即用户态内存,而操作系统的资源则没有被回收,这就需要我们定制__del__,在对象被删除前向操作系统发起关闭数据库链接的系统调用,回收资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class  Foo:
     def  __init__( self ,x):
         self .x = x
 
     def  __del__( self ):  #在对象资源被释放时触发
         print ( '-----del------' )
         print ( self )
 
f = Foo( 100000 )
del  f
print ( '=======================>'
# 析构方法__del__与文件处理原理差不多:
  
f = open ( 'a.txt' )   #做了两件事,在用户空间拿到一个f变量,在操作系统内核空间打开一个文件
del  f           #只回收用户空间的f,操作系统的文件还处于打开状态
  
#所以我们应该在del f之前保证f.close()执行,即便是没有del,程序执行完毕也会自动del清理资源,于是文件操作的正确用法应该是
f = open ( 'a.txt' )
f.close()   # f.close就相当于析构方法__del__,在回收用户空间的同时回收系统空间

 

7、异常处理

异常就是程序运行时发生错误的信号(在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止)

错误有两种:

a.语法错误(在语法检测阶段抛出,必须在程序执行前就改正)

b.逻辑错误

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
TypeError       # 类型错误
for  in  3 :
     pass
 
NameError       # 名称错误
aaaaa
 
ValueError      # 值错误
int ( 'asdfsadf' )
 
IndexError      # 索引错误
l = [ 1 , 2 ]
l[ 1000 ]
 
KeyError        # key错误
d = { 'a' : 1 }
d[ 'b' ]
 
AttributeError  # 属性错误
class  Foo: pass 
Foo.x

 

常见异常:

AttributeError      试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x

IOError       输入/输出异常;基本上是无法打开文件

ImportError      无法引入模块或包;基本上是路径问题或名称错误

IndentationError      语法错误(的子类) ;代码没有正确对齐

IndexError   下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]

KeyError     试图访问字典里不存在的键

KeyboardInterrupt   Ctrl+C被按下

NameError   使用一个还未被赋予对象的变量

SyntaxError Python   代码非法,代码不能编译(个人认为这是语法错误,写错了)

TypeError   传入对象类型与要求的不符合

UnboundLocalError  试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它

ValueError   传入一个调用者不期望的值,即使值的类型是正确的

 

异常处理

a. 如果错误发生的条件是可预知的,我们需要用if进行处理:在错误发生之前进行预防

1
2
3
4
5
6
7
8
AGE = 10
while  True :
     age = input ( '>>: ' ).strip()
     if  age.isdigit():  #只有在age为字符串形式的整数时,下列代码才不会出错,该条件是可预知的
         age = int (age)
         if  age  = =  AGE:
             print ( 'you got it' )
             break

 

b. 如果错误发生的条件是不可预知的,则需要用到try...except:在错误发生之后进行处理

异常类只能用来处理指定的异常情况,如果非指定异常则无法处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
try :
     aaaa         # 抛出NameError异常
     print ( '==-==>1' )
     l = []
     l[ 3 ]         # 抛出IndexError异常
     print ( '==-==>2' )
     d = {}
     d[ 'x' ]       # 抛出KeyError异常
     print ( '==-==>3'
# 多分支异常
except  NameError as e:
     print (e)
except  IndexError as e:
     print (e)
except  KeyError as e:
     print (e)
except  Exception as e:        # 万能异常,能捕捉到所有的异常
     print (e)
else :
     print ( '在没有错误的时候执行' )
finally :
     print ( '无论有无错误,都会执行' )

 

c.主动抛出异常

1
2
3
4
try :
     raise  TypeError( '类型错误' )
except  Exception as e:
     print (e)

 

d.自定义异常

1
2
3
4
5
6
7
class  EgonException(BaseException):
     def  __init__( self ,msg):
         self .msg = msg
     def  __str__( self ):
         return  '<%s>'  % self .msg
 
raise  EgonException( 'egon 的异常' )

 

e.断言

assert

本文转自lyndon博客51CTO博客,原文链接http://blog.51cto.com/lyndon/1961399如需转载请自行联系原作者


迟到的栋子

相关文章
|
1月前
|
Python
python-面向对象
python-面向对象
14 2
|
5月前
|
Python
74 python - 打飞机案例(显示控制玩具飞机-面向对象)
74 python - 打飞机案例(显示控制玩具飞机-面向对象)
32 0
|
1月前
|
Java 程序员 数据安全/隐私保护
Python教程第6章 | Python面向对象
Python面向对象概念、类的定义和调用、类方法、修改和增加类属性、类和对象、初始化函数、类的继承、类的多态、类的访问控制
40 0
|
1月前
|
Python
|
2月前
|
机器学习/深度学习 人工智能 IDE
Python是一种高级、解释型、交互式和面向对象的脚本语言
Python是一种高级、解释型、交互式和面向对象的脚本语言
23 2
|
3月前
|
Python
【Python30天速成计划】6. 面向对象的继承和多态
【Python30天速成计划】6. 面向对象的继承和多态
|
3月前
|
Python
python 面向对象之继承
python 面向对象之继承
|
3月前
|
Python
Python基础学习 -- 面向对象
Python基础学习 -- 面向对象
15 0
|
3月前
python-pathlib模块使用 --- 面向对象的文件系统路径
python-pathlib模块使用 --- 面向对象的文件系统路径
20 0
|
3月前
|
算法 Python 容器
Python之变量命名、运算符和面向对象
【1月更文挑战第1天】 1、注释 注释分为单行注释和多行注释两种,单行注释用#表示,多行注释用(三个双引号"“”“”")或‘(三个单引号’‘’‘’')表示。如下所示:
102 2
Python之变量命名、运算符和面向对象