10年老司机,写好 Python 代码的几条重要技巧!

面向对象编程中的六大原则 面向对象编程中的六大原则1. 单一职责原则(Single Responsibility Principle)2. 里氏替换原则(Liskov Substitution Principle)3. 依赖倒置原则(Dependence Inversion Principle)4. 接口隔离原则(Interface Segregation Principle)5. 迪米特法则(Law Of Demeter)6. 开闭原则(Open Close Principle)总结 1. 单一职责原则(Single Respon 阅读详情

 

来源:NightTeam-韦世东


程序设计的好与坏,早在我们青葱岁月时就接触过了,只是那是并不知道这竟如此重要。能够立即改善程序设计、写出“好”代码的知识有以下几点:

•面向对象五个基本原则;•常见的三种架构;•绘图;•起一个好名字;•优化嵌套的 if else 代码;

当然,其他技术知识的丰富程度也决定了程序设计的好坏。例如通过引入消息队列解决双端性能差异问题、通过增加缓存层提高查询效率等。下面我们一起来看看,上面列出的知识点包含哪些内容,这些内容对代码和程序设计的改善有何帮助。

面向对象五个基本原则

本书作者是 2010 级学生,面向对象是作者青葱时期发展火热的编程范式。它的五个基本原则是:

•单一职责原则;•开放封闭原则;•依赖倒置原则;•接口隔离原则;•合成复用原则;

下面我们将通过对比和场景假设的方式了解五个基本原则对代码质量的影响。

立竿见影的单一职责原则

没错,立竿见影、效果卓越。对于我们这些自学编程无师自通的人来说,能把功能实现就可以了,根本没有时间考虑代码优化和维护成本问题。时光流逝,竟在接触编程很长一段时间后才发现它竟如此重要。

俗话说只要代码写的够烂,提升就足够明显。以一个从文件内容中匹配关键数据并根据匹配结果发出网络请求的案例,看看大部分程序员的写法:

import re
import requests


FILE = "./information.fet"


def extract(file):
    fil = open(file, "r")
    content = fil.read()
    fil.close()
    find_object = re.search(r"url=\d+", content)
    find = find_object.group(1)
    text = requests.get(find)
    return text


if __name__ == "__main__":
    text = extract(FILE)
    print(text)

需求已经实现,这点毋庸置疑,但是问题来了:

•如果读取文件的时候发生异常了怎么办?•如果数据源发生变化该如何处理?•如果网络请求返回的数据不符合最终要求怎么办?

如果你心里的第一个反应是改代码,那你就要注意了。完成一件事中间的某个环节发生变化,改代码是在所难免的,但是如果按照上面这种写法,不仅代码越改越乱,连逻辑也会越来越乱。单一职责原则表达的是让一个函数尽量只做一件事,不要将多件事混杂在一个函数中。

上面的代码如果重新设计,我认为至少应该是这样的:

def get_source():
    """获取数据源"""
    return


def extract_(val):
    """匹配关键数据"""
    return


def fetch(val):
    """发出网络请求"""
    return


def trim(val):
    """修剪数据"""
    return


def extract(file):
    """提取目标数据"""
    source = get_source()
    content = extract_(source)
    text = trim(fetch(content))
    return text


if __name__ == "__main__":
    text = extract(FILE)
    print(text)

把原来放在一个函数中实现的多个步骤拆分成为多个更小的函数,每个函数只做一件事。当数据源发生变化时,只需要改动 get_source 相关的代码即可;如果网络请求返回的数据不符合最终要求,我们可以在 trim 函数中对它进行修剪。这样一来,代码应对变化的能力提高了许多,整个流程也变得更清晰易懂。改动前后的变化如下图所示:

单一职责原则的核心是解耦和增强内聚力,如果一个函数承担的职责过多,等于把这些职责耦合在一起,这种耦合会导致脆弱的设计。当发生变化时,原本的设计会遭受到意想不到的破坏。单一职责原则实际上是把一件事拆分成多个步骤,代码修改造成的影响范围很小。

让代码稳定性飞升的开放封闭原则和依赖倒置原则

开放封闭原则中的开放指的是对扩展开放,封闭指的是对修改封闭。需求总是变化的,业务方这个月让你把数据存储到 MySQL 数据库中,下个月就有可能让你导出到 Excel 表格里,这时候你就得改代码了。这个场景和上面的单一职责原则很相似,同样面临代码改动,单一职责原则示例主要表达的是通过解耦降低改动的影响,这里主要表达的是通过对扩展开放、对修改封闭提高程序应对变化的能力和提高程序稳定性。

稳定这个词如何理解呢?

较少的改动或者不改动即视为稳定,稳定意味着调用这个对象的其它代码拿到的结果是可以确定的,整体是稳定的。

按照一般程序员的写法,数据存储的代码大概是这样的:

class MySQLSave:

    def __init__(self):
        pass

    def insert(self):
        pass

    def update(self):
        pass


class Business:
    def __init__(self):
        pass

    def save(self):
        saver = MySQLSave()
        saver.insert()

功能是能够实现的,这点毋庸置疑。来看看它如何应对变化,如果要更换存储,那么就意味着需要改代码。按照上面的代码示例,有两个选择:

•重新写一个存储到 ExcelSave 的类;•对 MySQLSave 类进行改动;

上面的两种选择,无论怎么选都会改动 2 个类。因为不仅存储的类需要改动,调用处的代码也需要更改。这样一来,它们整体都是不稳定的。如果换一种实现方式,根据依赖倒置的设计指导可以轻松应对这个问题。边看代码边理解:

import abc


class Save(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def insert(self):
        pass

    @abc.abstractmethod
    def update(self):
        pass


class MySQLSave(Save):

    def __init__(self):
        self.classify = "mysql"
        pass

    def insert(self):
        pass

    def update(self):
        pass


class Excel(Save):
    def __init__(self):
        self.classify = "excel"

    def insert(self):
        pass

    def update(self):
        pass


class Business:
    def __init__(self, saver):
        self.saver = saver

    def insert(self):
        self.saver.insert()

    def update(self):
        self.saver.update()


if __name__ == "__main__":
    mysql_saver = MySQLSave()
    excel_saver = Excel()
    business = Business(mysql_saver)

这里通过内置的 abc 实现了一个抽象基类,这个基类的目的是强制子类实现要求的方法,以达到子类功能统一。子类功能统一后,无论调用它的哪个子类,都是稳定的,不会出现调用方还需要修改方法名或者修改传入参数的情况。

依赖倒置中的倒置,指的是依赖关系的倒置。之前的代码是调用方 Business 依赖对象 MySQLSave,一旦对象 MySQLSave 需要被替换, Business 就需要改动。依赖倒置中的依赖指的是对象的依赖关系,之前依赖的是实体,如果改为后面这种依赖抽象的方式,情况就会扭转过来:

实体 Business 依赖抽象有一个好处:抽象稳定。相对于多变的实体来说,抽象更稳定。代码改动前后的依赖关系发生了重大变化,之前调用方 Business 直接依赖于实体 MySQLSave,通过依赖倒置改造后 Busines 和 ExcelSave、 MySQLSave 全都依赖抽象。

这样做的好处是如果需要更换存储,只需要创建一个新的存储实体,然后调用 Business 时传递进去即可,这样可以不用改动 Business 的代码,符合面向修改封闭、面向扩展开放的开放封闭原则;

依赖倒置的具体实现方式使用了一种叫做依赖注入的手段,实际上单纯使用依赖注入、不使用依赖倒置也可以满足开闭原则要求,感兴趣的读者不妨试一试。

挑肥拣瘦的接口隔离原则

接口隔离原则中的接口指的是 Interface,而不是 Web 应用里面的 Restful 接口,但是在实际应用中可以将其抽象理解为相同的对象。接口隔离原则在设计层面看,跟单一职责原则的目的是一致的。接口隔离原则的指导思想是:

•调用方不应该依赖它不需要的接口;•依赖关系应当建立在最小接口上;

这实际上是告诉我们要给接口减肥,过多功能的接口可以选用拆分的方式优化。举个例子,现在为图书馆设计一个图书的抽象类:

import abc


class Book(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def buy(self):
        pass

    @abc.abstractmethod
    def borrow(self):
        pass

    @abc.abstractmethod
    def shelf_off(self):
        pass

    @abc.abstractmethod
    def shelf_on(self):
        pass

图可以被购买、可以被借阅、可以下架、可以上架,这看起来并没有什么问题。但这样一来这个抽象只能提供给管理人员使用,用户操作时需要再设定一个新的抽象类,因为你不可能让用户可以操纵图书上下架。接口隔离原则推荐的做法是把图书的上下架和图书购买、借阅分成 2 个抽象类,管理端的图书类继承 2 个抽象类,用户端的图书类继承 1 个抽象类。这么看起来是有点绕,不要慌,我们看图理解:

这样是不是一下就看懂了。这个指导思想很重要,不仅能够指导我们设计抽象接口,也能够指导我们设计 Restful 接口,还能够帮助我们发现现有接口存在的问题,从而设计出更合理的程序。

轻装上阵的合成复用原则

合成复用原则的指导思想是:尽量使用对象组合,而不是继承来达到复用的目的。合成复用的作用是降低对象之间的依赖,因为继承是强依赖关系,无论子类使用到父类的哪几个属性,子类都需要完全拥有父类。合成采用另一种方式实现对象之间的关联,降低依赖关系。

为什么推荐优先使用合成复用,而后考虑继承呢?

搜索公众号顶级架构师后台回复“offer”,获取一份惊喜礼包。

因为继承的强依赖关系,一旦被依赖的对象(父类)发生改变,那么依赖者(子类)也需要改变,合成复用则可以避免这样的情况出现。要注意的是,推荐优先使用复用,但并不是拒绝使用继承,该用的地方还得用。我们以一段代码为例,说明合成复用和继承的差异:

import abc


class Car:

    def move(self):
        pass

    def engine(self):
        pass


class KateCar(Car):

    def move(self):
        pass

    def engine(self):
        pass


class FluentCar(Car):

    def move(self):
        pass

    def engine(self):
        pass

这里的 Car 作为父类,拥有 move 和 engine 2 个重要属性,这时候如果需要给汽车涂装颜色,那么就要新增一个 color 属性,3 个类都要增加。如果使用合成复用的方式,可以这么写:

class Color:
    pass


class KateCar:

    color = Color()

    def move(self):
        pass

    def engine(self):
        pass


class FluentCar:

    color = Color()

    def move(self):
        pass

    def engine(self):
        pass

类对象合成复用的具体操作是在类中实例化一个类对象,然后在需要的时候调用它。代码可能没有那么直观,我们看图:

这个例子主要用于说明继承和合成复用的具体实现方式和前后变化,对于 Car 的继承无需深究,因为如果你执着地讨论为什么右图中的 2 个 Car 不用继承,就会陷入牛角尖。

这里的合成复用选用的实现方式是在 2 个 Car 里面实例化另一个类 Color,其实也可以用依赖注入的手段在外部实例化 Color,然后把实例对象传递给 2 个 Car。

常见的三种架构

了解多种不同的架构可以使我们的知识面更宽广,面对一类问题的时候可以提出其它解决办法。同时,了解多种架构可以让我们在设计阶段做好规划,避免后续频繁的重构。常见的三种架构分别是:

•单体架构;•分布式架构;•微服务架构;

单体架构

单体架构是我们平时接触较多的架构,也是相对容易理解的架构。单体架构把所有功能都聚合在一个应用里,我们可以简单地将这种架构视作:

这种架构简单、容易部署和测试,大部分应用的初期都采用单体架构。单体架构也有几个明显缺点:

•复杂性高,所有功能糅合在一个应用里,模块多、容易出现边界模糊,而且随着时间的推移和业务的发展,项目越来越大、代码越来越多,整体服务效率逐渐下降;•发布/部署频率低,牵一发而动全身,新功能或问题修复的发布上线需要多方协调,发布时间一拖再拖。项目大则构建时间长、构建失败的几率也会有所增加;•性能瓶颈明显,一头牛再厉害也抵不过多头牛合力的效果,随着数据量、请求并发的增加,读性能的不足最先暴露出来,接着你就会发现其它方面也跟不上了;•影响技术创新:单体架构通常选用一类语言或一类框架统一开发,想要引入新技术或者接入现代化的服务是很困难的;•可靠性低,一旦服务出现问题,影响是巨大的。

分布式架构

分布式架构相对于单体架构而言,通过拆分解决了单体架构面临的大部分问题,例如性能瓶颈。假如单体架构是一头牛,那么分布式架构就是多头牛:

当单体架构出现性能瓶颈时,团队可以考虑将单体架构转换为分布式架构,以增强服务能力。当然,分布式并不是万能的,它解决了单体架构性能瓶颈、可靠性低的问题,但复杂性问题、技术创新问题和发布频率低依然存在,这时候可以考虑微服务。

微服务架构

微服务架构的关键字是拆,将原本糅合在一个应用中的多个功能拆成多个小应用,这些小应用串联起来组成一个与之前单体架构功能相同的完整应用。具体示意如下:

每个微服务可以独立运行,它们之间通过网络协议进行交互。每个微服务可以部署多个实例,这样一来就具备了跟分布式架构相同的性能。单个服务的发布/部署对其它服务的影响较小,在代码上没有关联,因此可以频繁的发布新版本。复杂性的问题迎刃而解,拆分之后架构逻辑清晰、功能模块职责单一,功能的增加和代码的增加也不会影响到整体效率。服务独立之后,项目就变得语言无关,评价服务可以用 Java 语言来实现也可以用 Golang 语言实现,不再受到语言或者框架的制约,技术创新问题得以缓解。

这是不是很像单一职责原则和接口隔离原则?

分布式和微服务并不是银弹

从上面的对比来看,似乎分布式架构比单体架构好,微服务架构比分布式架构好,这么说来微服务架构>分布式架构>单体架构?

这么理解是不对的,架构需要根据场景和需求选择,微服务架构和分布式架构看上去很美,但也衍生出了许多新问题。以微服务架构为例:

•运维成本高,在单体架构时,运维只需要保证 1 个应用正常运行即可,关注的可能只是硬件资源消耗问题。但如果换成微服务架构,应用的数量成百上千,当应用出现问题或者多应用之间协调异常时,运维人员的头就会变大;•分布式系统固有的复杂性,网络分区、分布式事务、流量均衡对开发者和运维进行了敲打;•接口调整成本高,一个接口的调用方可能有很多个,如果设计时没有遵循开放封闭原则和接口隔离原则,那么调整的工作量会是非常大的;•接口性能受限,原本通过函数调用的方式交互,在内存中很快就完成了,换成接口后通过网络进行交互,性能明显下降;•重复劳动,虽然有公共模块,但如果语言无关且又要考虑性能(不用接口交互)就需要自己实现一份相同功能的代码;

到底用哪种架构,需要根据具体的场景来选择。如果你的系统复杂度并没有那么高、性能追求也没有那么高,例如一个日数据量只有几万的爬虫应用,单体架构就足以解决问题,不需要强行做成分布式或者微服务,因为这样只会增加自己的工作量。

画好图

在需要表达关系和逻辑梳理的场景里,图永远比代码好。业内流行这么一句话“程序开发,设计先行”,说的是在开发前,需要对程序进行构思和设计。试想,如果连对象关系和逻辑都说不清楚,写出的代码会是好代码吗?

在构思项目时可以使用用例图挖掘需求和功能模块;在架构设计时可以使用协作图梳理模块关系;在设计接口或者类对象时可以使用类图做好交互计划;在功能设计时可以使用状态图帮助我们挖掘功能属性……

了解绘图的重要性之后,具体的绘图方法和技巧可翻阅本书(《Python 编程参考》)的工程师绘图指南章节展开学习。

起一个好名字

你还记得自己曾经起过的那些名字吗:

•reversalList•get_translation•get_data•do_trim•CarAbstract

起一个好的、合适的名字能够让代码风格更统一,看上去清晰了然。起一个好名字不单单是单词语法的问题,还会涉及风格选择和用途。具体的命名方法和技巧可翻阅本书(《Python 编程参考》)的命名选择与风格指南章节展开学习。

优化嵌套的 if else 代码

写代码的时候用一些控制语句是很正常的事,但是如果 if else 嵌套太多,也是非常头疼的,代码看上去就像下面这样。

搜索公众号顶级架构师后台回复“面试”,获取一份惊喜礼包。

这种结构的产生是因为使用了 if 语句来进行先决条件的检查,如果负责条件则进入下一行代码,如果不符合则停止。既然这样,那我们在先决条件的检查上进行取反即可,代码改动过后看起来像这样:
if "http" not in url:
        return
if "www" not in url:
        return
这是我平时常用的优化办法,后来在张晔老师的付费专栏中看到这种手段的名称——卫语句。

当然,这种简单的逻辑处理和 if else 控制流用卫语句进行处理是很有效的,但如果逻辑再复杂一些,用卫语句的效果就不见的那么好了。假设汽车 4S 店有折扣权限限制,普通销售有权对 30 万以内金额的汽车授予一定折扣,超过 30 万但在 80 万以内需要精英销售进行授权,更高价格的车折扣需要店长授权。这个功能可以归纳为根据金额的大小来确定授权者,对应代码如下:

def buying_car(price):
    if price < 300000:
        print("普通销售")
    elif price < 800000:
        print("精英销售")
    elif price < 1500000:
        print("店长")

代码思路清晰,但存在的问题也明显。如果以后扩展价格和定级,会增加更多的 if else 语句,代码将变得臃肿。控制语句的顺序是固定在代码中的,如果想要调整顺序,只能修改控制语句。

那么问题来了,有比 if else 更合适的办法吗?

这时候可以考虑一种叫做责任链的设计模式,责任链设计模式的定义为:为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

看起来有点绕,我们通过代码图加深理解:

处理类执行前根据先决条件判断自身的 handler 是否能够处理,如果不能则交给 next_handler,也就是责任链的下一个节点。上面的用责任链实现为:

class Manager:

    def __init__(self,):
        self.obj = None

    def next_handler(self, obj):
        self.obj = obj

    def handler(self, price):
        pass


class General(Manager):

    def handler(self, price):
        if price < 300000:
            print("{} 普通销售".format(price))
        else:
            self.obj.handler(price)


class Elite(Manager):

    def handler(self, price):
        if 300000 <= price < 800000:
            print("{} 精英销售".format(price))
        else:
            self.obj.handler(price)


class BOSS(Manager):

    def handler(self, price):
        if price >= 800000:
            print("{} 店长".format(price))

创建好抽象类和具体的处理类之后,它们还没有关联关系。我们需要将它们挂载到一起,成为一个链条:

general = General()
elite = Elite()
boss = BOSS()
general.next_handler(elite)
elite.next_handler(boss)

这里建立的责任链顺序为 General -> Elite -> BOSS,调用方只需要传递价格给 General,如果它没有折扣的授予权它会交给 Elite 处理,如果 Elite 没有折扣授予权则会交给 BOSS 处理。对应代码如下:

    prices = [550000, 220000, 1500000, 200000, 330000]
    for price in prices:
        general.handler(price)  

这跟我们去 4S 店购车是一样的,作为客户,我们确定好要买的车即可,至于 4S 店如何申请折扣,谁来授权与我无关,我能拿到相应的折扣即可。

至此,if else 优化知识学习完毕。

左手Python,右手Java,升职就业不愁啦!



推荐阅读:
入门: 最全的零基础学Python的问题  | 零基础学了8个月的Python  | 实战项目 |学Python就是这条捷径
干货:爬取豆瓣短评,电影《后来的我们》 | 38年NBA最佳球员分析 |   从万众期待到口碑扑街!唐探3令人失望  | 笑看新倚天屠龙记 | 灯谜答题王 |用Python做个海量小姐姐素描图 |碟中谍这么火,我用机器学习做个迷你推荐系统电影
趣味:弹球游戏  | 九宫格  | 漂亮的花 | 两百行Python《天天酷跑》游戏!
AI: 会做诗的机器人 | 给图片上色 | 预测收入 | 碟中谍这么火,我用机器学习做个迷你推荐系统电影
小工具: Pdf转Word,轻松搞定表格和水印! | 一键把html网页保存为pdf!|  再见PDF提取收费! | 用90行代码打造最强PDF转换器,word、PPT、excel、markdown、html一键转换 | 制作一款钉钉低价机票提示器! |60行代码做了一个语音壁纸切换器天天看小姐姐!|

年度爆款文案

点阅读原文,领AI全套资料
【动手学树莓派】8年老司机谈嵌入式系统的未来 嵌入式未来10年的如何发展 截止到2018年,嵌入式系统发展一直处于不温不火状态,还记得2012年在读硕士期间,老师曾给过两幅图片:一幅高楼大厦、灯火通明、另一幅小小的村落、点点灯光。高楼大厦代表的互联网行业,一直处于蓬勃发展;而嵌入式则一直处于小村落状态。但万事万物的发展都是由逐步的量变转为质变,目前嵌入式蓬勃发展的三个基本条件已经成熟,未来的嵌入式必将迈入AIOT(AIOT=AI+IOT)时代。 咱们先看看三个基本条件:算力的提升和SOC的成熟、5G的商业化普及、硬件友好性深度学习算法的逐步成熟。 1. 阅读详情

相关推荐

全网最新首发纯干货:微信数据库表结构完整分析(一)

找不到微信DB表结构说明?找不到具体字段的解释?来这里,全网最完整版!!!

killghosts的博客 4930

00-设计模式原则

文章目录1 单一职责原则2 开闭原则3 里氏代换原则4 依赖倒转原则5 接口隔离原则6 迪米特法则7 合成复用原则 1 单一职责原则 对于类来说,**一个类应该只负责一种职责。**如果类A负责两个不同的职责:职责1,职责2。当职责1需求变更而改变A时,可能造成职责2执行错误,所以需要将类A的粒度分解为A1,A2。 2 开闭原则 **对扩展开放,对修改关闭。**在程序需要进行扩展的时候,不能去修改原有的代码。 需要使用接口和抽象类。只要抽象合理,可以基本保持可以基本保持软件架构的稳定。而软件中易变的细节可以从

Seven_Year1的博客 589

从零开始用TS开发babylonjs - 本机环境搭建

babylonjs,初始化本地安装,web3d引擎

han3527638的专栏 798

写好 Python 代码的几条重要技巧

程序设计的好与坏,早在我们青葱岁月时就接触过了,只是那是并不知道这竟如此重要。能够立即改善程序设计、写出“好”代码的知识有以下几点: •面向对象五个基本原则;•常见的三种架构;•绘图;•起一个好名字;•优化嵌套的 if else 代码; 当然,其他技术知识的丰富程度也决定了程序设计的好坏。例如通过引入消息队列解决双端性能差异问题、通过增加缓存层提高查询效率等。下面我们一起来看看,上面列出的知识点包含哪些内容,这些内容对代码和程序设计的改善有何帮助。 面向对象五个基本原则 本书作者是 2010 级学生

m0_50414588的博客 440

AMD Ryzen AI Max+ 395四机集群实战:开源工具链与大模型推理优化全解析

本文详细解析了基于AMD Ryzen AI Max+ 395处理器的四机集群搭建与优化实践,涵盖硬件配置、开源工具链评测及大模型推理优化技巧。通过深度测试,揭示了集群在AI推理中的性能瓶颈与解决方案,特别适合需要扩展显存的大模型实验场景。文章还提供了成本效益分析,帮助开发者做出更明智的选型决策。

weixin_29041767的博客 1528

飞牛fnNAS搭建web版微信

摘要:本文介绍了一种通过Docker在飞牛NAS上部署微信客户端的方法,实现24小时同步微信聊天记录。具体步骤包括:1)激活飞牛NAS的Docker功能并配置镜像加速源;2)创建专用文件夹并下载docker-wechat镜像;3)设置容器参数并部署微信客户端;4)通过局域网或ZeroTier内网穿透实现远程访问。相比传统Windows/Linux方案,该方法资源占用更低,适合需要长期保存微信聊天记录的用户。

dgnankai的专栏 3343

面向对象编程七大编程原则概述详解

面向对象编程原则概述 1.1 软件的可维护性和可复用性 可维护性较低的软件设计,通常由于如下四个原因造成: 过于僵硬(Rigidity) :灵活性不够 过于脆弱(Fragility) :健壮性(鲁棒性) 不够复用率低(Immobility) :不能重用 黏度过高(Viscosity) :高耦合,关联性太高 一个好的系统设计应该具备如下三个性质: 可扩展性(Extensibility) 灵活性(Flexibility) 可插入性(Pluggability) 程序设计原则:高内聚,低耦合 面向对象编程的

Pluto372的博客 1946

双像素传感器的AI计算摄影实战:单目深度估计与图像去模糊的融合创新

本文介绍了双像素传感器技术在计算机视觉中的应用,包括深度估计、图像去模糊和图像重建等任务。双像素传感器通过两个子单元捕捉视差信息,使摄像头能够分析场景的三维结构和运动轨迹。文章以图像去模糊为例,详细展示了从数据准备到模型训练的完整流程,包括构建自定义数据集、设计双像素特征提取模块、训练去模糊模型及推理测试。通过模拟双像素的"双视角"信息融合,该AI算法能有效恢复模糊图像的清晰细节。

know_F0727的博客 256

面向对象编程的6大原则

面向对象编程的6大原则:单一职责原则、开闭原则、里式替换原则、依赖倒置原则、接口隔离原则和迪米特法则。

qq_44720283的博客 648

为什么idea已经改了UTF-8还是乱码,如何解决?

🏆本文收录于 《全栈Bug调优(实战版)》 专栏,该专栏专注于分享我在真实项目开发中遇到的各类疑难Bug及其深层成因,并系统提供高效、可复现的解决思路和实操方案。无论你是刚入行的新手开发者,还是拥有多年项目经验的资深工程师,本专栏都将为你提供一条系统化、高质量的问题排查与优化路径,助力你加速成长,攻克技术壁垒,迈向技术价值最大化与职业发展的更高峰🚀!

**My Coding Family** 1579

价值投资中的AI驱动现金流预测:多智能体协作模型

在价值投资领域,准确的现金流预测是做出明智投资决策的关键。传统的现金流预测方法往往依赖于历史数据和简单的统计模型,难以应对复杂多变的市场环境和企业经营状况。随着人工智能技术的快速发展,利用AI驱动的模型进行现金流预测成为了研究热点。本文的目的在于介绍一种基于多智能体协作的模型,用于提高价值投资中现金流预测的准确性和可靠性。本文的范围涵盖了多智能体协作模型的核心概念、算法原理、数学模型、项目实战、实际应用场景以及相关工具和资源推荐等方面,旨在为读者提供一个全面且深入的关于AI驱动现金流预测的知识体系。

AI 算法实战派 679

10年老司机,写好 Python 代码的几条重要技巧

程序设计的好与坏,早在我们青葱岁月时就接触过了,只是那是并不知道这竟如此重要。能够立即改善程序设计、写出“好”代码的知识有以下几点: •面向对象五个基本原则;•常见的三种架构;•绘图;•起一个好名字;•优化嵌套的 if else 代码; 当然,其他技术知识的丰富程度也决定了程序设计的好坏。例如通过引入消息队列解决双端性能差异问题、通过增加缓存层提高查询效率等。下面我们一起来看看,上面列出的知识点包含哪些内容,这些内容对代码和程序设计的改善有何帮助。 面向对象五个基本原则 本书作者是 2010 级学生,面向.

python_9988的博客 251

一文掌握DrissionPage的详细使用

是一个基于 Python 的网页自动化工具,主要用于网页数据的抓取、自动化操作和测试。它结合了 Selenium 和 Requests 的优点,提供了更简洁、高效的 API,适用于各种网页自动化任务。DrissionPage 是一个功能强大且易于使用的网页自动化工具,适用于各种网页自动化任务。希望本文的 DrissionPage 的基本使用方法和一些高级功能能够帮助到你。

数据知道的博客 1万+

十年老司机告诉你,python都能用来做什么?

一提到python,大家脑袋中都会想到「数据分析」、「爬虫」、「人工智能」这些词。

m0_59236602的博客 583

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

MATLAB正在被Python按在地上摩擦?从业8年老司机告诉你真实答案!

实验室师兄的博士论文代码,是导师的导师传下来的MATLAB脚本。这种学术界的"嫡系传承",导致很多学科(特别是传统工科)的教学资源严重MATLAB化。问负责人为啥不用Python,得到的回答直击灵魂:“我们的仿真模型都是十年起步的迭代成果,换成Python要重写验证,这成本你出吗?结果45%的人投了"已经在被取代",32%的人选"永远不会",剩下的在吃瓜。作为同时用MATLAB和Python接过私活的老码农(光接MATLAB仿真项目就赚了辆五菱宏光),今天必须唠唠这个事儿!抱歉,白嫖党永远的神!

GDShrc的博客 814

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

python省略号怎么打_十年老司机告诉你,python都能用来做什么?

一提到python,大家脑袋中都会想到「数据分析」、「爬虫」、「人工智能」这些词。其实python并没有像如上所说的这样「专业」、「高深」的应用,对于初学者来说更是可以从一些超简单又有趣的小项目开始着手。比如:自动寄送 Email首先,我们先认识一下 SMTP(Simple Mail Transfer Protocol),也就是简单邮件传输协议,它是一组用于「由来源地址到目的地址传送邮件的协议」,...

weixin_39992072的博客 420

测试工程师究竟有多吃香?10年老司机真实经历告诉你!

下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】​​​。

Hacker_Oldv的博客 604

Python程序如何高效地调试?五年老司机告诉你

Python在debug方面的支持还是不错的,在明确代码意义的情况下,通过log、print和assert分析错误原因,配合单元测试可以很高效。然而,实际工作中大量代码很可能出自他人之手,这种情况下,使用debugger就显得更加高效了。 一、在控制台下进行程序调试 PDB 如果你熟悉命令行调试工具(例如gdb、lldb),那么使用Python中的PDB将获得非常好的体验,PDB不仅支持项目启动时进行调用,也支持在Python shell中交互式调试;功能上,支持断点、步进、异常捕获和解决、变量查看、变量

码农黑羽的博客 724

【python实用小脚本-55】Python爬虫抓取汽车数据,10年老司机的权威背书:效率提升90%(建议收藏)

这段Python代码的核心功能是通过Selenium自动化浏览器操作,动态加载网页数据,并提取关键信息保存为CSV文件。它不仅可以用于抓取汽车数据,还可以扩展到电商价格监测、社交媒体舆情分析等多个场景。希望这篇文章能帮助你更好地理解和应用Python爬虫技术,提升工作效率。这个案例的完整源码已开源在我的GitCode仓库,可自行搜索下载。如果需要完整可运行的版本,可到这里下载:https://pan.quark.cn/s/654cf649e5a6 提取码:f5VG。

kylner的博客 931

2024年老司机带你用python从另外一个角度看市场需求~,2024年最新面试经历分享网站

Python崛起并且风靡,因为优点多、应用领域广、被大牛们认可。学习 Python 门槛很低,但它的晋级路线很多,通过它你能进入机器学习、数据挖掘、大数据,CS等更加高级的领域。Python可以做网络应用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!python 3.8 解释器。

m0_60721823的博客 867

Python内存泄漏排查实战——9年老司机带你用tracemalloc和objgraph精准定位问题

本文分享了排查Flask应用内存泄漏的实战经验。通过一个用户行为分析系统的案例,展示了如何使用Python自带的tracemalloc和第三方工具objgraph定位内存泄漏点。文章详细介绍了排查步骤:确认泄漏存在、定位问题代码、分析对象引用关系、验证修复效果,并提供了三级防御解决方案(自动清理、LRU缓存、监控预警)。最后总结了5条避坑经验:慎用全局变量、缓存设置过期机制、资源管理、打破循环引用和常态化监控。还推荐了日常开发和生产环境使用的工具链,帮助开发者有效预防和解决内存泄漏问题。

小陈工的博客 406

企业网络营销怎么样做?8年老司机随便开开车

网络营销真的是一个大到有点让人懵比的概念,其实本来就是多变的没有任何的固定模式,所以策划网络推广方案,其实并没有一种固定的通用的格式,也没有必要有一种固定的格式。但殊途同归的是,无论怎样策划网络营销,终极的目的都是为了卖出产品,提供服务,帮企业带来客户,帮老板赚钱盈利,这就要求策划网络营销方案的时候有方向性与目的性。 从九十年代互联网兴起,到如今互联网无处不在,各种行业都想触网,搞点互联网+笔者...

涛哥的营销运营思考 842

【VSCode AI调试终极指南】:20年老司机亲授5大避坑技巧与3个必装AI插件清单

本教程解决VSCode中AI辅助调试常见失效难题,涵盖断点联动、上下文注入、模型响应追踪等5大避坑技巧,适配Copilot、Tabnine等主流AI插件。提供3个经实测的必装AI调试插件清单及配置要点,提升智能补全与错误定位效率,值得收藏。

LiteCompile的博客 334

【Python MCP服务器开发避坑指南】:20年老司机亲授5大高频致命错误及秒级修复方案

Python MCP服务器开发避坑指南:直击5大高频致命错误,提供秒级修复方案与开箱即用模板。适用于微服务架构、AI代理集成等场景,融合异步通信、协议校验与热重载设计。稳定性强、调试效率高,值得收藏。

AlgoPerch的博客 433
上一篇: 跟你说个笑话,我毕业2年了,天天人肉提数...
下一篇: 简易版“美颜”来了!肝了一夜!用Python做一个高瘦脸神器!
菜鸟学Python
博客等级 码龄9年 8089粉丝 571原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值