优秀的编程知识分享平台

网站首页 > 技术文章 正文

面向对象 3(面向对象3个特性)

nanyue 2024-09-09 04:53:16 技术文章 5 ℃

内置函数补充

  • classmethod、staticmethod、property 。
  • callable,是否可在后面加括号执行。
    • 函数
def func():
    pass

print( callable(func) ) # True

class Foo(object):
    pass

print( callable(Foo) ) # True

类中具有__call__方法的对象

class Foo(object):
	pass

obj = Foo()
print( callable(obj) ) # False  
class Foo(object):

    def __call__(self, *args, **kwargs):
        pass
    
obj = Foo()
print( callable(obj) ) # True

所以当你以后在见到下面的情况时,首先就要想到handler可以是:函数、类、具有call方法的对象 这三种,到底具体是什么,需要根据代码的调用关系才能分析出来。

def do_something(handler):
    handler()

异常处理

在程序开发中如果遇到一些 不可预知的错误 或 你懒得做一些判断 时,可以选择用异常处理来做。

import requests

while True:
    url = input("请输入要下载网页地址:")
    res = requests.get(url=url)
    with open('content.txt', mode='wb') as f:
        f.write(res.content)

上述下载视频的代码在正常情况下可以运行,但如果遇到网络出问题,那么此时程序就会报错无法正常执行。

try:
    res = requests.get(url=url)
except Exception as e:
    代码块,上述代码出异常待执行。
print("结束")
import requests

while True:
    url = input("请输入要下载网页地址:")
    
    try:
        res = requests.get(url=url)
    except Exception as e:
        print("请求失败,原因:{}".format(str(e)))
        continue
        
    with open('content.txt', mode='wb') as f:
        f.write(res.content)
num1 = input("请输入数字:")
num2 = input("请输入数字:")
try:
    num1 = int(num1)
    num2 = int(num2)
    result = num1 + num2
    print(result)
except Exception as e:
    print("输入错误")

以后常见的应用场景:

  • 调用微信的API实现微信消息的推送、微信支付等
  • 支付宝支付、视频播放等
  • 数据库 或 redis连接和操作
  • 调用第三方的视频播放发的功能,由第三方的程序出问题导致的错误。

异常处理的基本格式:

try:
    # 逻辑代码
except Exception as e:
    # try中的代码如果有异常,则此代码块中的代码会执行。
try:
    # 逻辑代码
except Exception as e:
    # try中的代码如果有异常,则此代码块中的代码会执行。
finally:
    # try中的代码无论是否报错,finally中的代码都会执行,一般用于释放资源。

print("end")

"""
try:
    file_object = open("xxx.log")
    # ....
except Exception as e:
    # 异常处理
finally:
    file_object.close()  # try中没异常,最后执行finally关闭文件;try有异常,执行except中的逻辑,最后再执行finally关闭文件。
"""    

异常细分

import requests

while True:
    url = input("请输入要下载网页地址:")
    
    try:
        res = requests.get(url=url)
    except Exception as e:
        print("请求失败,原因:{}".format(str(e)))
        continue
        
    with open('content.txt', mode='wb') as f:
        f.write(res.content)

之前只是简单的捕获了异常,出现异常则统一提示信息即可。如果想要对异常进行更加细致的异常处理,则可以这样来做:

import requests
from requests import exceptions

while True:
    url = input("请输入要下载网页地址:")
    try:
        res = requests.get(url=url)
        print(res)    
    except exceptions.MissingSchema as e:
        print("URL架构不存在")
    except exceptions.InvalidSchema as e:
        print("URL架构错误")
    except exceptions.InvalidURL as e:
        print("URL地址格式错误")
    except exceptions.ConnectionError as e:
        print("网络连接错误")
    except Exception as e:
        print("代码出现错误", e)
        
# 提示:如果想要写的简单一点,其实只写一个Exception捕获错误就可以了。

如果想要对错误进行细分的处理,例如:发生Key错误和发生Value错误分开处理。

基本格式:

try:
    # 逻辑代码
    pass

except KeyError as e:
    # 小兵,只捕获try代码中发现了键不存在的异常,例如:去字典 info_dict["n1"] 中获取数据时,键不存在。
    print("KeyError")

except ValueError as e:
    # 小兵,只捕获try代码中发现了值相关错误,例如:把字符串转整型 int("无诶器")
    print("ValueError")

except Exception as e:
    # 王者,处理上面except捕获不了的错误(可以捕获所有的错误)。
    print("Exception")

Python中内置了很多细分的错误,供你选择。

常见异常:
"""
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问n x[5]
KeyError 试图访问字典里不存在的键 inf['xx']
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
"""
更多异常:......

自定义异常&抛出异常

上面都是Python内置的异常,只有遇到特定的错误之后才会抛出相应的异常。

其实,在开发中也可以自定义异常。

class MyException(Exception):
    pass
try:
    pass
except MyException as e:
    print("MyException异常被触发了", e)
except Exception as e:
    print("Exception", e)    

上述代码在except中定义了捕获MyException异常,但他永远不会被触发。因为默认的那些异常都有特定的触发条件,例如:索引不存在、键不存在会触发IndexError和KeyError异常。

对于我们自定义的异常,如果想要触发,则需要使用:raise MyException()类实现。

class MyException(Exception):
    pass


try:
    # 。。。
    raise MyException()
    # 。。。
except MyException as e:
    print("MyException异常被触发了", e)
except Exception as e:
    print("Exception", e)
class MyException(Exception):
    def __init__(self, msg, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.msg = msg


try:
    raise MyException("xxx失败了")
except MyException as e:
    print("MyException异常被触发了", e.msg)
except Exception as e:
    print("Exception", e)
class MyException(Exception):
    title = "请求错误"


try:
    raise MyException()
except MyException as e:
    print("MyException异常被触发了", e.title)
except Exception as e:
    print("Exception", e)

案例一:你我合作协同开发,你调用我写的方法。

  • 我定义了一个函数
class EmailValidError(Exception):
    title = "邮箱格式错误"

class ContentRequiredError(Exception):
    title = "文本不能为空错误"
    
def send_email(email,content):
    if not re.match("\w+@live.com",email):
        raise EmailValidError()
	if len(content) == 0 :
        raise ContentRequiredError()
	# 发送邮件代码...
    # ...
  • 你调用我写的函数
def execute():
    # 其他代码
    # ...
    
	try:
        send_email(...)
    except EmailValidError as e:
        pass
    except ContentRequiredError as e:
        pass
    except Exception as e:
        print("发送失败")

execute()

# 提示:如果想要写的简单一点,其实只写一个Exception捕获错误就可以了。

案例二:在框架内部已经定义好,遇到什么样的错误都会触发不同的异常。

import requests
from requests import exceptions

while True:
    url = input("请输入要下载网页地址:")
    try:
        res = requests.get(url=url)
        print(res)    
    except exceptions.MissingSchema as e:
        print("URL架构不存在")
    except exceptions.InvalidSchema as e:
        print("URL架构错误")
    except exceptions.InvalidURL as e:
        print("URL地址格式错误")
    except exceptions.ConnectionError as e:
        print("网络连接错误")
    except Exception as e:
        print("代码出现错误", e)
        
# 提示:如果想要写的简单一点,其实只写一个Exception捕获错误就可以了。

特殊的finally

try:
    # 逻辑代码
except Exception as e:
    # try中的代码如果有异常,则此代码块中的代码会执行。
finally:
    # try中的代码无论是否报错,finally中的代码都会执行,一般用于释放资源。

print("end")

当在函数或方法中定义异常处理的代码时,要特别注意finally和return。

def func():
    try:
        return 123
    except Exception as e:
        pass
    finally:
        print(666)
        
func()

在try或except中即使定义了return,也会执行最后的finally块中的代码。

练习题

  1. 补充代码实现捕获程序中的错误。
  2. # 迭代器
    class IterRange(object):
    def __init__(self, num):
    self.num = num
    self.counter = -1

    def __iter__(self):
    return self

    def __next__(self):
    self.counter += 1
    if self.counter == self.num:
    raise StopIteration()
    return self.counter


    obj = IterRange(20)

    while True:
    try:
    ele = next(obj)
    except StopIteration as e:
    print("数据获取完毕")
    break
    print(ele)
  3. 补充代码实现捕获程序中的错误。
  4. class IterRange(object):
    def __init__(self, num):
    self.num = num
    self.counter = -1

    def __iter__(self):
    return self

    def __next__(self):
    self.counter += 1
    if self.counter == self.num:
    raise StopIteration()
    return self.counter


    class Xrange(object):
    def __init__(self, max_num):
    self.max_num = max_num

    def __iter__(self):
    return IterRange(self.max_num)


    data_object = Xrange(100)
    obj_iter = data_object.__iter__()

    while True:
    try:
    ele = next(obj_iter)
    except StopIteration as e:
    print("数据获取完毕")
    break
    print(ele)
  5. 补充代码实现捕获程序中的错误。
  6. def func():
    yield 1
    yield 2
    yield 3

    gen = func()
    while True:
    try:
    ele = next(gen)
    except StopIteration as e:
    print("数据获取完毕")
    break
    print(ele)
  7. 补充代码实现捕获程序中的错误。(注意:本案例用于练习,在真是开发中对于这种情况建议还是自己做判断处理,不要用异常)
  8. num = int("武沛齐")try:
    num = int("武沛齐")
    except ValueError as e:
    print("转换失败")
  9. 补充代码实现捕获程序中的错误。(注意:本案例用于练习,在真是开发中对于这种情况建议还是自己做判断处理,不要用异常)
  10. data = [11,22,33,44,55]
    data[1000]try:
    data = [11,22,33,44,55]
    data[1000]
    except IndexError as e:
    print("转换失败")
  11. 补充代码实现捕获程序中的错误。(注意:本案例用于练习,在真是开发中对于这种情况建议还是自己做判断处理,不要用异常)
  12. data = {"k1":123,"k2":456}
    data["xxxx"]try:
    data = {"k1":123,"k2":456}
    data["xxxx"]
    except KyeError as e:
    print("转换失败")
  13. 分析代码,写结果
  14. class MyDict(dict):

    def __getitem__(self, item):
    try:
    return super().__getitem__(item) # KeyError
    except KeyError as e:
    return None


    info = MyDict()
    info['name'] = "武沛齐"
    info['wx'] = "wupeiq666"

    print(info['wx']) # info['wx'] -> __getitem__
    print(info['email']) # info['email'] -> __getitem__
  15. 看代码写结果
  16. def run(handler):
    try:
    num = handler()
    print(num)
    return "成功"
    except Exception as e:
    return "错误"
    finally:
    print("END")

    print("结束")


    res = run(lambda: 123)
    print(res)>>> 123
    >>> END
    >>> 成功def func():
    print(666)
    return "成功"

    def run(handler):
    try:
    num = handler()
    print(num)
    return func()
    except Exception as e:
    return "错误"
    finally:
    print("END")

    print("结束")


    res = run(lambda: 123)
    print(res)>>> 123
    >>> 666
    >>> END
    >>> 成功



Tags:

最近发表
标签列表