python面向对象(4)

简介: python面向对象(4)

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

  • 我定义了一个函数
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捕获错误就可以了。

案例三:按照规定去触发指定的异常,每种异常都具备被特殊的含义。

96447814-120fc980-1245-11eb-938d-6ea408716c72.png

3.4 特殊的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. 补充代码实现捕获程序中的错误。
# 迭代器
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)

补充代码实现捕获程序中的错误。

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)

补充代码实现捕获程序中的错误。

def func():
    yield 1
    yield 2
    yield 3
gen = func()
while True:
    try:
        ele = next(gen)
    except StopIteration as e:
        print("数据获取完毕")
        break
    print(ele)

补充代码实现捕获程序中的错误。(注意:本案例用于练习,在真是开发中对于这种情况建议还是自己做判断处理,不要用异常)

num = int("lbw")
try:
    num = int("lbw")
except ValueError as e:
    print("转换失败")

补充代码实现捕获程序中的错误。(注意:本案例用于练习,在真是开发中对于这种情况建议还是自己做判断处理,不要用异常)

data = [11,22,33,44,55]
data[1000]
try:
    data = [11,22,33,44,55]
    data[1000]
except IndexError as e:
    print("转换失败")

补充代码实现捕获程序中的错误。(注意:本案例用于练习,在真是开发中对于这种情况建议还是自己做判断处理,不要用异常)

data = {"k1":123,"k2":456}
data["xxxx"]
try:
    data = {"k1":123,"k2":456}
    data["xxxx"]
except KyeError as e:
    print("转换失败")

分析代码,写结果

class MyDict(dict):
    def __getitem__(self, item):
        try:
            return super().__getitem__(item) # KeyError
        except KeyError as e:
            return None
info = MyDict()
info['name'] = "lbw"
info['wx'] = "lbw666"
print(info['wx'])     # info['wx']  -> __getitem__
print(info['email'])  # info['email']  -> __getitem__

看代码写结果

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
>>> 成功

4.反射

反射,提供了一种更加灵活的方式让你可以实现去 对象 中操作成员(以字符串的形式去 对象 中进行成员的操作)。

class Person(object):
    def __init__(self,name,wx):
        self.name = name
        self.wx = wx
    def show(self):
        message = "姓名{},微信:{}".format(self.name,self.wx)
user_object = Person("lbw","lbw666")
# 对象.成员 的格式去获取数据
user_object.name
user_object.wx
user_object.show()
# 对象.成员 的格式无设置数据
user_object.name = "lbw"
user = Person("lbw","lbw666")
# getattr 获取成员
getattr(user,"name") # user.name
getattr(user,"wx")   # user.wx
method = getattr(user,"show") # user.show
method()
# 或
getattr(user,"show")()
# setattr 设置成员
setattr(user, "name", "lbw") # user.name = "lbw"

Python中提供了4个内置函数来支持反射:

  • getattr,去对象中获取成员
v1 = getattr(对象,"成员名称")
v2 = getattr(对象,"成员名称", 不存在时的默认值)

setattr,去对象中设置成员

setattr(对象,"成员名称",值)

hasattr,对象中是否包含成员

v1 = hasattr(对象,"成员名称") # True/False

delattr,删除对象中的成员

delattr(对象,"成员名称")

以后如果再遇到 对象.成员 这种编写方式时,均可以基于反射来实现。

案例:

class Account(object):
    def login(self):
        pass
    def register(self):
        pass
    def index(self):
        pass
def run(self):
    name = input("请输入要执行的方法名称:") # index register login xx run ..
    account_object = Account()
    method = getattr(account_object, name,None) # index = getattr(account_object,"index")
    if not method:
        print("输入错误")
        return 
    method()

4.1 一些皆对象

在Python中有这么句话:一切皆对象。 每个对象的内部都有自己维护的成员。

  • 对象是对象
class Person(object):
    def __init__(self,name,wx):
        self.name = name
        self.wx = wx
    def show(self):
        message = "姓名{},微信:{}".format(self.name,self.wx)
user_object = Person("lbw","lbw666")
user_object.name

类是对象

class Person(object):
    title = "lbw"
Person.title
# Person类也是一个对象(平时不这么称呼)

模块是对象

import re
re.match
# re模块也是一个对象(平时不这么称呼)。

由于反射支持以字符串的形式去对象中操作成员【等价于 对象.成员 】,所以,基于反射也可以对类、模块中的成员进行操作。

简单粗暴:只要看到 xx.oo 都可以用反射实现。

class Person(object):
    title = "lbw"
v1 = Person.title
print(v1)
v2 = getattr(Person,"title")
print(v2)
import re
v1 = re.match("\w+","dfjksdufjksd")
print(v1)
func = getattr(re,"match")
v2 = func("\w+","dfjksdufjksd")
print(v2)

4.2 import_module + 反射

在Python中如果想要导入一个模块,可以通过import语法导入;企业也可以通过字符串的形式导入。

示例一:

# 导入模块
import random
v1 = random.randint(1,100)
# 导入模块
from importlib import import_module
m = import_module("random")
v1 = m.randint(1,100)

示例二:

# 导入模块exceptions
from requests import exceptions as m
# 导入模块exceptions
from importlib import import_module
m = import_module("requests.exceptions")

示例三:

# 导入模块exceptions,获取exceptions中的InvalidURL类。
from requests.exceptions import InvalidURL
# 错误方式
from importlib import import_module
m = import_module("requests.exceptions.InvalidURL") # 报错,import_module只能导入到模块级别。
# 导入模块
from importlib import import_module
m = import_module("requests.exceptions")
# 去模块中获取类
cls = m.InvalidURL

在很多项目的源码中都会有 import_modulegetattr 配合实现根据字符串的形式导入模块并获取成员,例如:

from importlib import import_module
path = "openpyxl.utils.exceptions.InvalidFileException"
module_path,class_name = path.rsplit(".",maxsplit=1) # "openpyxl.utils.exceptions"   "InvalidFileException"
module_object = import_module(module_path)
cls = getattr(module_object,class_name)
print(cls)

我们在开发中也可以基于这个来进行开发,提高代码的可扩展性,例如:请在项目中实现一个发送 短信、微信 的功能。

参考示例代码中的:auto_message 项目。

总结

  1. 了解 mro和c3算法
  2. python2和python3在面向对象中的区别。
  3. 内置函数
staticmethod,classmethod,property,callable,type,isinstance,issubclass,super
getattr,setattr,hasattr,delattr
  1. 异常处理
  2. 根据字符串的形式导入模块 import_module
  3. 根据字符串的形式操作成员 反射-getattr,setattr,hasattr,delattr
相关文章
|
4月前
|
Java 程序员 C++
Python 面向对象详解!
本文详细介绍了Python中的面向对象编程(OOP),包括类、对象、继承、封装、多态和抽象等核心概念。通过具体示例,解释了如何使用类定义对象的属性和方法,以及如何通过继承实现代码重用。文章还探讨了封装和多态的重要性,并介绍了私有属性和抽象类的使用方法。最后,总结了OOP的四大支柱:封装、抽象、继承和多态,强调了这些概念在Python编程中的应用。适合Java程序员扩展Python编程知识。
113 2
|
2月前
|
关系型数据库 开发者 Python
Python编程中的面向对象设计原则####
在本文中,我们将探讨Python编程中的面向对象设计原则。面向对象编程(OOP)是一种通过使用“对象”和“类”的概念来组织代码的方法。我们将介绍SOLID原则,包括单一职责原则、开放/封闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则有助于提高代码的可读性、可维护性和可扩展性。 ####
|
6月前
|
Python
你真的会面向对象吗!解密Python“魔术方法”
你真的会面向对象吗!解密Python“魔术方法”
65 0
|
4月前
|
Python
Python面向对象(2)
【10月更文挑战第14天】
Python面向对象(2)
|
4月前
|
设计模式 程序员 C语言
Python面向对象
【10月更文挑战第13天】
Python面向对象
|
8月前
|
Python
Python进阶第一篇(Python的面向对象)
Python进阶第一篇(Python的面向对象)
|
9月前
|
存储 算法 安全
Python编程实验六:面向对象应用
Python编程实验六:面向对象应用
136 1
|
5月前
|
前端开发 Python
Python编程的面向对象有哪些(二)
Python编程的面向对象(二)—类的多态
37 7
|
5月前
|
IDE Java 开发工具
Python类与面向对象
Python类与面向对象
|
9月前
|
人工智能 自然语言处理 开发者
Python基础教程——面向对象
Python基础教程——面向对象

热门文章

最新文章