上篇我们已经了解了一些面向对象的基础知识,本次就了解下面向对象的一些进阶知识(虽然我也不知道有什么卵用)。
静态方法
静态方法是一种普通函数,就位于类定义的命名空间中,它不会对任何实例类型进行操作。使用装饰器@staticmethod定义静态方法。类对象和实例都可以调用静态方法;
说了那么多,估计会有些懵逼,咱们还是直接上代码看下静态方法怎么使用吧!
1.按照正常逻辑编写代码并加上@staticmethod定义静态方法eat:
1
2
3
4
5
6
7
8
9
10
|
class People( object ): def __init__( self ,name): self .name = name @staticmethod #把eat方法变为静态方法 def eat( self ): print ( "%s is eating" % self .name) d = People( "cc" ) d.eat() |
运行上面代码,我们会发现报以下错误:
TypeError: eat() missing 1 required positional argument: 'self'
----------eat需要一个self参数,但调用时却没有传递
so...我们可以得出一个结论:eat变成静态方法后,再通过实例调用时不会自动把实例本身当作一个参数传给self
2.解决办法:
1)调用时主动传递实例本身给eat方法,即d.eat(d)
2)在eat方法中去掉self参数(这也意味着,在eat中不能通过self.调用实例中的其它变量了)
类方法
类方法是将类本身作为对象进行操作的方法。类方法使用@classmethod装饰器定义,其第一个参数是类,约定写为cls。类对象和实例都可以调用类方法。
类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量。
依然还是原来的代码,把eat变为类方法看下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
class People( object ): def __init__( self , name): self .name = name @classmethod # 把eat方法变为类方法 def eat( self ): print ( "%s is eating" % self .name) d = People( "cc" ) d.eat() - - - - - - - - - - - - - - - 打印输出 - - - - - - - - - - - - - - - - - - - print ( "%s is eating" % self .name) AttributeError: type object 'People' has no attribute 'name' |
报错说明:People没有name属性;
上面说过,类方法只能访问类变量,不能访问实例变量,而name在这里就是实例变量。
我们加上一个类变量试试:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
class People( object ): name = "类变量" def __init__( self , name): self .name = name @classmethod # 把eat方法变为类方法 def eat( self ): print ( "%s is eating" % self .name) d = People( "cc" ) d.eat() - - - - - - - - - - - - - - - - - - - - 打印输出 - - - - - - - - - - - - - - - - - - - 类变量 is eating |
属性方法
属性方法的作用就是通过@property把一个方法变成一个静态属性;
依然还是之前的代码,把eat方法变成静态属性看下效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class People( object ): name = "请叫我类变量" def __init__( self , name): self .name = name @property # 把eat方法变为静态属性 def eat( self ): print ( "%s is eating" % self .name) d = People( "cc" ) d.eat() - - - - - - - - - - - - - - - - - 打印输出 - - - - - - - - - - - - - - - - - - - - d.eat() TypeError: 'NoneType' object is not callable |
这里报错是因为eat已经变成了一个静态属性,当然不能再使用()去调用了,我们直接调用试试:
1
2
3
4
|
d.eat - - - - - - - - - - - - - 打印输出 - - - - - - - - - - - - cc is eating |
反射
1.反射的定义
根据字符串的形式去某个对象中操作成员
- 根据字符串的形式去一个对象中寻找成员
- 根据字符串的形式去一个对象中设置成员
- 根据字符串的形式去一个对象中删除成员
- 根据字符串的形式去一个对象中判断成员是否存在
2. 反射的函数
-
getattr(object, name[, default])
根据字符串的形式去一个对象中寻找成员
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class People( object ): def __init__( self ): self .name = 'cc' def eat( self ): return 'HI' d = People() ret1 = getattr (d, 'eat' ) ret2 = getattr (d, 'name' ) r1 = ret1() print (r1) print (ret2) - - - - - - - - - - - - - - 打印输出 - - - - - - - - - - - - - - - - HI cc |
-
setattr(object, name, value)
根据字符串的形式去一个对象中设置成员
1
2
3
4
5
6
7
8
9
10
11
12
|
class People( object ): def __init__( self ): self .name = 'cc' def eat( self ): return 'HI' d = People() set1 = setattr (d, 'age' , 18 ) r1 = getattr (d, 'age' ) print (r1) - - - - - - - - - - - - - - - - - - - - - - - 打印输出 - - - - - - - - - - - - - - - - - - - - - - - - - - - 18 |
-
delattr(object, name)
根据字符串的形式去一个对象中删除成员
1
2
3
4
5
6
7
8
9
10
11
12
|
class People( object ): def __init__( self ): self .name = 'cc' def eat( self ): return 'HI' d = People() del1 = delattr (d, 'name' ) r1 = getattr (d, 'name' ) print (r1) - - - - - - - - - - - - - - - - 打印输出 - - - - - - - - - - - - - - - - - - - AttributeError: 'People' object has no attribute 'name' |
-
hasattr(object, name)
根据字符串的形式去一个对象中判断成员是否存在
1
2
3
4
5
6
7
8
9
10
11
12
|
class People( object ): def __init__( self ): self .name = 'cc' def eat( self ): return 'HI' d = People() h1 = hasattr (d, 'age' ) h2 = hasattr (d, 'name' ) print (h1,h2) - - - - - - - - - - - - - - - 打印输出 - - - - - - - - - - - - - - - - - False True |
异常处理(缺少else和finally)
在之前学习的过程中我们会接触到各式各样的报错信息,编程过程中为了增加友好性,可以抓取相对应的错误并给出提示信息。
常用异常:
更多异常:
常用异常实例:
IndexError(输出指定错误信息并打印错误信息)
1
2
3
4
5
6
7
8
9
|
dic = [ 1 , 2 ] try : dic[ 2 ] except IndexError as e : print ( "i got it!
" ,e) - - - - - - - - - - - - - - - - - - - - - - - - - - - 打印输出 - - - - - - - - - - - - - - - - - - - - - - - - - - i got it! list index out of range |
KeyError(输出指定错误信息并打印错误信息)
1
2
3
4
5
6
7
8
9
10
|
dic = { 'name' : 'cc' } try : dic[ 'age' ] except KeyError as e : print ( "i got it!
" ,e) - - - - - - - - - - - - - - - - - - - - - - - - - - - 打印输出 - - - - - - - - - - - - - - - - - - - - - - - - - - - i got it! 'age' |
ValueError
1
2
3
4
5
6
7
8
9
|
s1 = 'hello' try : int (s1) except ValueError as e: print (e) - - - - - - - - - - - - - - - - - - - - - - - - - - - 打印输出 - - - - - - - - - - - - - - - - - - - - - - - - - - - - invalid literal for int () with base 10 : 'hello' |
万能异常Exception:(不建议用,不便于调试;可与异常配合使用)
1
2
3
4
5
6
7
8
9
|
s1 = 'hello' try : int (s1) except KeyError as e: print ( '键错误' ) except IndexError as e: print ( '索引错误' ) except Exception as e: print ( '错误' ) |
自定义异常:
1
2
3
4
5
6
7
8
9
|
class ccException(Exception): def __init__( self ,msg): self .msg = msg def __str__( self ): return self .msg try : raise ccException( "我的异常" ) except ccException as e: print (e)<span style = "font-size: 14pt;" > < / span> |