python中面向对象的ui_Python 工匠:写好面向对象代码的原则(上)
发布日期:2021-09-13 06:38:44 浏览次数:2 分类:技术文章

本文共 3308 字,大约阅读时间需要 11 分钟。

????点击上方蓝字“Python猫”,免费获得一个公众号花下猫语:今天继续给大家分享一篇好文章,有助于 Python 进阶的。Python 是一门支持面向对象的语言,但它跟典型的面向对象语言不完全相同。如何在 Python 中写出良好的面向对象代码呢?全文较长,建议收藏后慢慢阅读。

图 | 宫崎骏电影《侧耳倾听》

作者:piglei  |  公众号:piglei

(本文经原作者授权转载,不得二次转载)

前言这是 “Python 工匠”系列的第 12 篇文章。

全系列地址:https://github.com/piglei/one-python-craftsman

Python 是一门支持多种编程风格的语言,面对相同的需求,拥有不同背景的程序员可能会写出风格迥异的 Python 代码。比如一位习惯编写 C 语言的程序员,通常会定义一大堆函数来搞定所有事情,这是“过程式编程”的思想。而一位有 Java 背景的程序员则更倾向于设计许多个相互关联的类(class),这是 “面向对象编程(后简称 OOP)”。

虽然不同的编程风格各有特点,无法直接比较。但是 OOP 思想在现代软件开发中起到的重要作用应该是毋庸置疑的。

很多人在学习如何写好 OOP 代码时,会选择从那 23 种经典的“设计模式”开始。不过对于 Python 程序员来说,我认为这并非是一个最佳选择。

Python 对 OOP 的支持

Python 语言虽然拥有类、继承、多态等核心 OOP 特性,但和那些完全基于 OOP 思想设计的编程语言(比如 Java)相比,它在 OOP 支持方面做了很多简化工作。比如它 没有严格的类私有成员,没有接口(Interface)对象 等。

而与此同时,Python 灵活的函数对象、鸭子类型等许多动态特性又让一些在其他语言中很难做到的事情变得非常简单。这些语言间的差异共同导致了一个结果:很多经典的设计模式到了 Python 里,就丢失了那个“味道”,实用性也大打折扣。

拿大家最熟悉的单例模式来说。你可以花上一大把时间,来学习如何在 Python 中利用 __new__ 方法或元类(metaclass)来实现单例设计模式,但最后你会发现,自己 95% 的需求都可以通过直接定义一个模块级全局变量来搞定。

所以,与具体化的 设计模式 相比,我觉得一些更为抽象的 设计原则 适用性更广、更适合运用到 Python 开发工作中。而谈到关于 OOP 的设计原则,“SOLID” 是众多原则中最有名的一个。

SOLID 设计原则

著名的设计模式书籍《设计模式:可复用面向对象软件的基础》出版于 1994 年,距今已有超过 25 年的历史。而这篇文章的主角:“SOLID 设计原则”同样也并不年轻。

早在 2000 年,Robert C. Martin 就在他的文章 "Design Principles and Design Patterns" 中整理并提出了 “SOLID” 设计原则的雏型,之后又在他的经典著作《敏捷软件开发 : 原则、模式与实践》中将其发扬光大。“SOLID” 由 5 个单词组合的首字母缩写组成,分别代表 5 条不同的面向对象领域的设计原则。

在编写 OOP 代码时,如果遵循这 5 条设计原则,就更可能写出可扩展、易于修改的代码。相反,如果不断违反其中的一条或多条原则,那么很快你的代码就会变得不可扩展、难以维护。

接下来,让我用一个真实的 Python 代码样例来分别向你诠释这 5 条设计原则。写在最前面的注意事项:“原则”不是“法律”,它只起到指导作用,并非不可以违反

“原则”的后两条与接口(Interface)有关,而 Python 没有接口,所以对这部分的诠释是我的个人理解,与原版可能略有出入

文章后面的内容含有大量代码,请做好心理准备 ☕️

为了增强代码的说明性,本文中的代码使用了 Python3 中的 类型注解特性

SOLID 原则与 Python

Hacker News(后简称 HN) 是一个在程序员圈子里很受欢迎的站点。在它的首页,有很多由用户提交后基于推荐算法排序的科技相关内容。

我经常会去上面看一些热门文章,但我觉得每次打开浏览器访问有点麻烦。所以,我准备编写一个脚本,自动抓取 HN 首页 Top5 的新闻标题与链接,并用纯文本的方式写入到文件。方便自己用其他工具阅读。

图:Hacker News 首页截图

编写爬虫几乎是 Python 天生的拿手好戏。利用 requests、lxml 等模块提供的好用功能,我可以轻松实现上面的需求。下面是我第一次编写好的代码:importio

importsys

fromtypingimportGenerator

importrequests

fromlxmlimportetree

classPost:

"""HN(https://news.ycombinator.com/) 上的条目

:param title: 标题

:param link: 链接

:param points: 当前得分

:param comments_cnt: 评论数

"""

def__init__(self, title: str, link: str, points: str, comments_cnt: str):

self.title = title

self.link = link

self.points = int(points)

self.comments_cnt = int(comments_cnt)

classHNTopPostsSpider:

"""抓取 HackerNews Top 内容条目

:param fp: 存储抓取结果的目标文件对象

:param limit: 限制条目数,默认为 5

"""

ITEMS_URL ='https://news.ycombinator.com/'

FILE_TITLE ='Top news on HN'

def__init__(self, fp: io.TextIOBase, limit: int =5):

self.fp = fp

self.limit = limit

deffetch(self) ->Generator[Post,None,None]:

"""从 HN 抓取 Top 内容

"""

resp = requests.get(self.ITEMS_URL)

# 使用 XPath 可以方便的从页面解析出你需要的内容,以下均为页面解析代码

# 如果你对 xpath 不熟悉,可以忽略这些代码,直接跳到 yield Post() 部分

html = etree.HTML(resp.text)

items = html.xpath('//table[@class="itemlist"]/tr[@class="athing"]')

foriteminitems[:self.limit]:

node_title = item.xpath('./td[@class="title"]/a')[0]

node_detail = item.getnext()

points_text = node_detail.xpath('.//span[@class="score"]/text()')

comments_text = node_detail.xpath('.//td/a[last()]/text()')[0]

yieldPost(

title=node_title.text,

link=node_title.get('href'),

# 条目可能会没有评分

points=points_text[0].split()[0]ifpoints_textelse'0',

comments_cnt=comments_text.split()[0]

)

defwrite_to_file(self):

"""以纯文本格式将 Top 内容写入文件

"""

转载地址:https://blog.csdn.net/weixin_39767645/article/details/110751746 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:python colormap_Python matplotlib的使用并自定义colormap的方法
下一篇:最厉害的象棋软件_象棋作弊史上最严重一幕出现,几百人被封号,很多的网络软件主播...

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年03月11日 10时55分56秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

druid不能close mysql连接_alibaba druid mysql连接问题 2019-04-21
mysql 设置按天分表_MySQL 优化实战记录 2019-04-21
java连接mysql 不推荐_java连接mysql 2019-04-21
mysql数据库 quota_shell脚本抓取用户存储quota写道mysql并展现到grafana面板 2019-04-21
idea测试连接mysql报错08001_IDEA连接MySQL错误 2019-04-21
layui导入模板数据_layui表格-template模板的三种用法 2019-04-21
mysql分组显示行号_mysql 显示行号,以及分组排序 2019-04-21
MySQL常见的主从复制架构_如何搭建经典的MySQL 主从复制架构 2019-04-21
编写python程序、计算账户余额_小明有20w存款存在余额宝中,按余额宝年收益为3.35%计算,用Python编写程序计算,多少年后小明的存款达到30w?... 2019-04-21
python 公众号引流_公众号引流方法有哪些? 2019-04-21
java 减少内存_java中减少内存占用小技巧 2019-04-21
centos 7 mysql图形界面_centos7-vnstat图形界面搭建 2019-04-21
java 防渗透_「java、工程师工作经验怎么写」-看准网 2019-04-21
java中跳出当前循环怎么做_在java中,如何跳出当前的多重循环? 2019-04-21
java程序中执行maven_java – 将一个enviornment变量传递给Maven中的已执行进程 2019-04-21
java16下载_java lombok下载 2019-04-21
python 图像处理与识别书籍_Python图像处理之识别图像中的文字(实例讲解) 2019-04-21
java安全初始化_java安全编码指南之:声明和初始化 2019-04-21
java jstat gc_分析JVM GC及内存情况的方法 2019-04-21
php pclzip.lib.php,php使用pclzip类实现文件压缩的方法(附pclzip类下载地址) 2019-04-21