首页 > 代码库 > python学习笔记-(十一)面向对象进阶&异常处理

python学习笔记-(十一)面向对象进阶&异常处理

上篇我们已经了解了一些面向对象的基础知识,本次就了解下面向对象的一些进阶知识(虽然我也不知道有什么卵用)。

 

静态方法

静态方法是一种普通函数,就位于类定义的命名空间中,它不会对任何实例类型进行操作。使用装饰器@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)
  
= People("cc")
d.eat()

运行上面代码,我们会发现报以下错误:

TypeError: eat() missing 1 required positional argument: ‘self‘

----------eat需要一个self参数,但调用时却没有传递

so...我们可以得出一个结论:eat变成静态方法后,再通过实例调用时不会自动把实例本身当作一个参数传给self

2.解决办法:

1)调用时主动传递实例本身给eat方法,即d.eat(d) 

+ View Code

2)在eat方法中去掉self参数(这也意味着,在eat中不能通过self.调用实例中的其它变量了)

+ View Code

类方法

类方法是将类本身作为对象进行操作的方法。类方法使用@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)
 
 
= 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)
 
= 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)
 
= 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‘
= 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‘
= 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‘
= 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‘
= People()
h1 = hasattr(d,‘age‘)
h2 = hasattr(d,‘name‘)
print(h1,h2)
 
---------------打印输出-----------------
False True

 

异常处理(缺少else和finally)

在之前学习的过程中我们会接触到各式各样的报错信息,编程过程中为了增加友好性,可以抓取相对应的错误并给出提示信息。

常用异常:

+ View Code

更多异常:

+ View Code

常用异常实例:

IndexError(输出指定错误信息并打印错误信息)

1
2
3
4
5
6
7
8
9
dic = [1,2]
try:
    dic[2]
except IndexError as e :
    print("i got it!\n",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!\n",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>

python学习笔记-(十一)面向对象进阶&异常处理