您当前的位置:首页 > 计算机 > 编程开发 > Python

python精选15集(补充、模块、异常)

时间:04-25来源:作者:点击数:

一、new方法【补充】

1、init方法是什么?

使用Python写过面向对象的代码的同学,可能对 init 方法已经非常熟悉了,init 方法通常用在初始化一个类实例的时候。例如:

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return '<Person: %s(%s)>' % (self.name, self.age)

if __name__ == '__main__':
    niwa = Person('Niwa', 24)
    print(niwa)

执行结果

<Person: Niwa(24)>

这样便是init最普通的用法了。但init其实不是实例化一个类的时候第一个被调用 的方法。当使用 Persion(name, age) 这样的表达式来实例化一个类时,最先被调用的方法 其实是new方法。

2、new方法又是什么?

new方法接受的参数虽然也是和init一样,但init是在类实例创建之后调用,而new方法正是创建这个类实例的方法。

class Person(object):
    """Silly Person"""

    def __new__(cls, name, age):
        print('__new__ called')
        return super().__new__(cls)

    def __init__(self, name, age):
        print('__init__ called.')
        self.name = name
        self.age = age

    def __str__(self):
        return '<Person: %s(%s)>' % (self.name, self.age)


if __name__ == '__main__':
    niwa = Person('Niwa', 24)
    print(niwa)

执行结果

__new__ called
__init__ called.
<Person: Niwa(24)>

我们比较两个方法的参数,可以发现__new__方法是传入类(cls),而__init__方法传入类的实例化对象(self),而有意思的是,__new__方法返回的值就是一个实例化对象(ps:如果__new__方法返回None,则__init__方法不会被执行,并且返回值只能调用父类中的__new__方法,而不能调用毫无关系的类的__new__方法)。我们可以这么理解它们之间的关系,__new__是开辟疆域的大将军,而__init__是在这片疆域上辛勤劳作的小老百姓,只有__new__执行完后,开辟好疆域后,__init__才能工作,结合到代码,也就是__new__的返回值正是__init__中self。

3、cls的用法

  • 定义: cls可以在静态方法中使用,并通过cls()方法来实例化一个对象。
class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        print('self:', self)

    # 定义一个build方法,返回一个person实例对象,这个方法等价于Person()。
    @classmethod
    def build(cls):
        # cls()等于Person()
        p = cls("Tom", 18)
        print('cls:', cls)
        return p


if __name__ == '__main__':
    person = Person.build()
    print(person, person.name, person.age)

执行结果

self: <__main__.Person object at 0x000002474096B3C8>
cls: <class '__main__.Person'>
<__main__.Person object at 0x000002474096B3C8> Tom 18

总结

  • __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供。
  • __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例。
  • __init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值。
  • 我们可以将类比作制造商,__new__方法就是前期的原材料购买环节,__init__方法就是在有原材料的基础上,加工,初始化商品环节

二、模块

  • python中的模块

有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt函数,必须用语句**#include

<math.h>**引入math.h这个头文件,否则是无法正常进行调用的。

  • 那么在Python中,如果要引用一些其他的函数,该怎么处理呢?
  • 在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在Python中要调用sqrt函数,必须用import关键字引入math这个模块,下面就来了解一下Python中的模块。
  • python中的包
  • 包: 当我们写了几个相近的py文件后, 想要集成起来给别人使用. 这时候就需要用到我们的包了.
  • 包就是为了多个py文件打包起来访问的东西. 只要在包里面放一个init.py文件, 在init.py文件import包里面的模块(py文件), 就可以实现"import 包名", 实现对多个模块的调用.

说的通俗点:模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块

1、import 语句

模块定义好后,我们可以使用 import 语句来引入模块,语法如下:

import module1[, module2[,... moduleN]]

比如要引用模块 math,就可以在文件最开始的地方用import math来引入。在调用 math 模块中的函数时,必须这样引用:

模块名.函数名

当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。

搜索路径是一个解释器会先进行搜索的所有目录的列表。如想要导入模块 support.py,需要把命令放在脚本的顶端:

一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。

2、 from…import 语句

Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。语法如下:

from modname import name1[, name2[, ... nameN]]

例如,要导入模块 fib 的 fibonacci 函数,使用如下语句:

from fib import fibonacci

这个声明不会把整个 fib 模块导入到当前的命名空间中,它只会将 fib 里的 fibonacci 单个引入到执行这个声明的模块的全局符号表。

3、from…import* 语句

把一个模块的所有内容全都导入到当前的命名空间也是可行的,只需使用如下声明:

from modname import *

这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。

例如我们想一次性引入 math 模块中所有的东西,语句如下:

from math import *

4、定位模块

当你导入一个模块,Python解析器对模块位置的搜索顺序是:

  • 当前目录
  • 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录。
  • 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/
  • 模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。

三、异常

1、定义

  • 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
  • 一般情况下,在Python无法正常处理程序时就会发生一个异常。
  • 异常是Python对象,表示一个错误。
  • 当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。

常见异常类型

  • 名称异常(NameError):变量未定义。
  • 类型异常(TypeError):不同类型数据进行运算。
  • 索引异常(IndexError):超出索引范围。
  • 属性异常(AttributeError):对象没有对应名称的属性。
  • 键异常(KeyError):没有对应名称的键。
  • 为实现异常(NotImplementedError):尚未实现的方法。
  • 异常基类Exception。

2、异常处理

捕捉异常可以使用try/except语句。

try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。

如果你不想在异常发生时结束你的程序,只需在try里捕获它。

语法:

以下为简单的try…except…else的语法:

try:
<语句>        #运行别的代码
except <名字>:
<语句>        #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句>        #如果引发了'name'异常,获得附加的数据
else:
<语句>        #如果没有异常发生

try的工作原理,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。

  • 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
  • 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。
  • 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。

演示案例

  • 需求:定义函数,在控制台中获取成绩(1–100),如果输入有误,请重新输入.
def get_score():
  while True:
    str_score = input("请输入成绩:")
    try:
      int_score = int(str_score)
    except ValueError:
      continue
    if 1<=int_score<=100:
      return int_score

print(get_score())

执行结果

请输入成绩:a
请输入成绩:101
请输入成绩:11
11

3、raise 语句

当程序出现错误,python会自动引发异常,也可以通过raise显示地引发异常。一旦执行了raise语句,raise后面的语句将不能执行。

try:
    s = None
    if s is None:
        print("s 是空对象")
        raise NameError  # 如果引发NameError异常,后面的代码将不能执行
    print(len(s))  # 这句不会执行,但是后面的except还是会走到
except TypeError:
    print("空对象没有长度")

s = None
if s is None:
    raise NameError
print('is here?')  # 如果不使用try......except这种形式,那么直接抛出异常,不会执行到这里

执行结果

s 是空对象
Traceback (most recent call last):
  File "E:/PyCharm_study_test/project/Learn_py/raise.py", line 5, in <module>
    raise NameError  # 如果引发NameError异常,后面的代码将不能执行
NameError

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门