亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解Python為什么不用設(shè)計(jì)模式

 更新時(shí)間:2021年06月24日 14:57:28   作者:有數(shù)可據(jù)  
今天給大家?guī)?lái)的是關(guān)于Python的相關(guān)知識(shí),文章圍繞著為什么Python不用設(shè)計(jì)模式展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下

前言

剛剛看了EuroPython 2017一篇演講,Why You Don't Need Design Patterns in Python,為什么python不用設(shè)計(jì)模式。演講者是STXNEXT的Sebastian Buczynski。

他對(duì)設(shè)計(jì)模式的定義是:

  • 常見(jiàn)問(wèn)題的通用可復(fù)用解決方案
  • 定型的最佳實(shí)踐

他說(shuō)設(shè)計(jì)模式是一種似曾相識(shí)(Anology),是一種大綱(Outline),他認(rèn)為設(shè)計(jì)模式并不是拿來(lái)就能用的。

Singleton

在這里插入圖片描述

第一個(gè)是Singleton模式,Singleton的精髓就是任何時(shí)候,只有一個(gè)類的實(shí)例。

《設(shè)計(jì)模式》里面給出的Singleton代碼是

聲明:

class Singleton {
public:
	static Singleton* Instance();
protected:
	Singleton();
private:
	static Singleton* _instance;
};

實(shí)現(xiàn):

Singleton* Singleton::_instance = 0;

Sebastian 在 Google 上面找Singleton的Python實(shí)現(xiàn),找到了以下代碼:

聲明:

class Singleton:
	_instance = None
	def __new__(cls, *args, **kwargs):
		if not cls._instance:
			cls._instance = super().__new__(cls, *args, **kwargs)
		return cls._instance

實(shí)現(xiàn):

one_instance = Singleton()
another_instance = Singleton()
one_instance is another_instance # True

Sebastian指出,照抄C++,當(dāng)然也可以解決問(wèn)題,但是在python里面有更好的解決方案。比如,可以用@classmethod。不過(guò),最好的解決方案是直接用module。因?yàn)閙odule本身就是唯一的,相當(dāng)于module就實(shí)現(xiàn)了singleton,那么,我們?yōu)槭裁匆筚M(fèi)周章,搞一個(gè)singleton出來(lái)呢?

我回憶了一下,盡管Singleton是最簡(jiǎn)單的設(shè)計(jì)模式了,但是,我這么多年一直沒(méi)用。以前寫C#的時(shí)候,我用的是靜態(tài)類,靜態(tài)類本身就是唯一的,所以我不需要singleton。當(dāng)然,我看到有人也用C#寫了和C++一樣的Singleton,但是我覺(jué)得解決問(wèn)題就可以了,沒(méi)必要為了寫設(shè)計(jì)模式而寫設(shè)計(jì)模式。同樣,寫VB.net的時(shí)候,我直接用的module,也不需要singleton。

結(jié)論:當(dāng)年《設(shè)計(jì)模式》里面的Singleton模式,是為了只有一個(gè)類實(shí)例。如果編程語(yǔ)言本身,如python, c#, vb.net,已經(jīng)提供了這樣的能力,就沒(méi)有必要再用C++的套路了?;蛘哒f(shuō),設(shè)計(jì)模式就不需要了。

Facade

在這里插入圖片描述
在這里插入圖片描述

(以上圖片來(lái)自參考[1])

Facade的基本概念是,子系統(tǒng)用Facade來(lái)屏蔽內(nèi)部的復(fù)雜實(shí)現(xiàn)。

這時(shí),我們可以把子系統(tǒng)的python文件統(tǒng)一放在一個(gè)文件夾里,然后在這個(gè)文件夾里放一個(gè)__init__.py文件。

在這里插入圖片描述

Command

Command模式把請(qǐng)求封裝成對(duì)象。

Sebastian認(rèn)為,在python里面,函數(shù)就是一等公民,所以沒(méi)有必要?jiǎng)?chuàng)建對(duì)象。

def command(discount_rate):
some_obj.notify_users_about_discount()

也可以用functools創(chuàng)建command

import functools
command = functools.partial(
some_obj.notify_users_about_discount, discount_rate=0.5
)
command()
# equals to
some_obj.notify_users_about_discount(discount_rate=0.5)

Visitor

Python里面沒(méi)有接口,沒(méi)有方法重載。那么怎么實(shí)現(xiàn)Visitor呢?

Sebastian指出,可以用@SingleDispatch。

from functools import singledispatch
@singledispatch
def visit(node):
	type_name = type(node).__name__
	raise AttributeError(f'No handler found for {type_name}')
from ast_nodes import Assign, FunctionDef
@visit.register(Assign)
def visit(node):
	pass
@visit.register(FunctionDef)
def visit(node):
	pass

我們看到,這里的實(shí)現(xiàn),并沒(méi)有class。

Decorator

Decorator可以用來(lái)擴(kuò)展一個(gè)對(duì)象。

它實(shí)現(xiàn)的方法是新建一個(gè)類,這個(gè)類和原來(lái)的類屬于同一個(gè)接口。然后這個(gè)類接受一個(gè)原來(lái)的類的對(duì)象,每個(gè)方法都調(diào)用原來(lái)的類的方法。

如果套用c++的《設(shè)計(jì)模式》,我們有

class OriginalClass:
	def get_text(self):
		pass
	def get_number(self):
		pass

    
class Decorator:
	def __init__(self, decorated_obj):
		self.decorated_obj = decorated_obj
	def get_text(self):
		return f'<b>{self.decorated_obj.get_text()}</b>'
	def get_number(self):
		return self.decorated_obj.get_number()

但是,這里可以用python的__getattr__特性來(lái)簡(jiǎn)化實(shí)現(xiàn)。

class Decorator:
	def __init__(self, decorated_obj):
		self.decorated_obj = decorated_obj
	def get_text(self):
		return f'{self.decorated_obj.get_text()}'
	def __getattr__(self, attr_name):
		return getattr(self.decorated_obj, attr_name)

總結(jié)

Sebastian指出,python非常靈活。和25年前的C++大相徑庭。很多地方,都非常容易插入邏輯。過(guò)去的設(shè)計(jì)模式,可能并不適用了。我們應(yīng)該很好的了解python,并借鑒其他語(yǔ)言,而不是生搬硬套。

我覺(jué)得,再好的東西,也要和實(shí)際相結(jié)合。任何脫離實(shí)際的做法,都是多余的,甚至有害的。任何理論,方法的產(chǎn)生,都有當(dāng)時(shí)的歷史背景,技術(shù)背景。如果不了解背后的機(jī)制,不了解背后的精神和目的,而是專注于招式本身,那只能是越來(lái)越僵化??此茍?jiān)持,實(shí)際上是背叛。堅(jiān)持是說(shuō)固執(zhí)的堅(jiān)持原來(lái)的做法,背叛是指背叛了初衷。

參考

[1] Why You Don't Need Design Patterns in Python

[2] Design Patterns – Elements of Reusable Object-Oriented Software

到此這篇關(guān)于詳解Python為什么不用設(shè)計(jì)模式的文章就介紹到這了,更多相關(guān)Python設(shè)計(jì)模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • flask中響應(yīng)錯(cuò)誤的處理及errorhandler的應(yīng)用方式

    flask中響應(yīng)錯(cuò)誤的處理及errorhandler的應(yīng)用方式

    這篇文章主要介紹了flask中響應(yīng)錯(cuò)誤的處理及errorhandler的應(yīng)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 基于python實(shí)現(xiàn)從尾到頭打印鏈表

    基于python實(shí)現(xiàn)從尾到頭打印鏈表

    這篇文章主要介紹了基于python實(shí)現(xiàn)從尾到頭打印鏈表,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Python實(shí)現(xiàn)ssh批量登錄并執(zhí)行命令

    Python實(shí)現(xiàn)ssh批量登錄并執(zhí)行命令

    本篇文章主要是介紹了Python實(shí)現(xiàn)ssh批量登錄并執(zhí)行命令,有一些任務(wù)可以進(jìn)行批量完成,Python就可以完成,有需要的同學(xué)可以了解一下。
    2016-10-10
  • python爬蟲 基于requests模塊的get請(qǐng)求實(shí)現(xiàn)詳解

    python爬蟲 基于requests模塊的get請(qǐng)求實(shí)現(xiàn)詳解

    這篇文章主要介紹了python爬蟲 基于requests模塊的get請(qǐng)求實(shí)現(xiàn)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • 跟老齊學(xué)Python之dict()的操作方法

    跟老齊學(xué)Python之dict()的操作方法

    這篇文章主要介紹了dict()的操作方法,由于dict的很多方法跟list類似,所以在詳細(xì)介紹dict的同時(shí),也跟list做了對(duì)比,是篇非常不錯(cuò)的文章,有需要的朋友參考下
    2014-09-09
  • Python繪圖Turtle庫(kù)的安裝問(wèn)題解決

    Python繪圖Turtle庫(kù)的安裝問(wèn)題解決

    這篇文章主要介紹了Python繪圖中解決Turtle的安裝問(wèn)題示例分析,也遇到過(guò)相同問(wèn)題的同學(xué)可以借鑒參考下,希望能夠解決你的問(wèn)題
    2021-10-10
  • django用戶注冊(cè)、登錄、注銷和用戶擴(kuò)展的示例

    django用戶注冊(cè)、登錄、注銷和用戶擴(kuò)展的示例

    本篇文章主要介紹了django用戶注冊(cè)、登錄、注銷和用戶擴(kuò)展的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-03-03
  • Python中用字符串調(diào)用函數(shù)或方法示例代碼

    Python中用字符串調(diào)用函數(shù)或方法示例代碼

    字符串作為python中常用的數(shù)據(jù)類型,掌握字符串的常用方法十分必要。下面這篇文章主要給大家介紹了關(guān)于Python中通過(guò)字符串調(diào)用函數(shù)或方法的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-08-08
  • Python使用微信itchat接口實(shí)現(xiàn)查看自己微信的信息功能詳解

    Python使用微信itchat接口實(shí)現(xiàn)查看自己微信的信息功能詳解

    這篇文章主要介紹了Python使用微信itchat接口實(shí)現(xiàn)查看自己微信的信息功能,結(jié)合實(shí)例形式分析了Python微信itchat模塊常見(jiàn)功能與操作技巧,需要的朋友可以參考下
    2019-08-08
  • 如何使用selenium和requests組合實(shí)現(xiàn)登錄頁(yè)面

    如何使用selenium和requests組合實(shí)現(xiàn)登錄頁(yè)面

    這篇文章主要介紹了如何使用selenium和requests組合實(shí)現(xiàn)登錄頁(yè)面,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02

最新評(píng)論