欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python 接口_從協(xié)議到抽象基類詳解

 更新時(shí)間:2017年08月24日 08:43:24   投稿:jingxian  
下面小編就為大家?guī)硪黄猵ython 接口_從協(xié)議到抽象基類詳解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

抽象基類的常見用途:實(shí)現(xiàn)接口時(shí)作為超類使用。然后,說明抽象基類如何檢查具體子類是否符合接口定義,以及如何使用注冊機(jī)制聲明一個(gè)類實(shí)現(xiàn)了某個(gè)接口,而不進(jìn)行子類化操作。最后,說明如何讓抽象基類自動(dòng)“識(shí)別”任何符合接口的類——不進(jìn)行子類化或注冊。

Python文化中的接口和協(xié)議

接口在動(dòng)態(tài)類型語言中是怎么運(yùn)作的呢?首先,基本的事實(shí)是,Python語言沒有 interface 關(guān)鍵字,而且除了抽象基類,每個(gè)類都有接口:類實(shí)現(xiàn)或繼承的公開屬性(方法或數(shù)據(jù)屬性),包括特殊方法,如__getitem__ 或 __add__。

按照定義,受保護(hù)的屬性和私有屬性不在接口中:即便“受保護(hù)的”屬性也只是采用命名約定實(shí)現(xiàn)的(單個(gè)前導(dǎo)下劃線);私有屬性可以輕松地訪問,原因也是如此。不要違背這些約定。

另一方面,不要覺得把公開數(shù)據(jù)屬性放入對象的接口中不妥,因?yàn)槿绻枰?,總能?shí)現(xiàn)讀值方法和設(shè)值方法,把數(shù)據(jù)屬性變成特性,使用obj.attr 句法的客戶代碼不會(huì)受到影響。 Vector2d 類就是這么做的,Vector2d 類的第一版,x 和 y 是公開屬性。

vector2d_v0.py:x 和 y 是公開數(shù)據(jù)屬性

class Vector2d:

 def __init__(self, x, y):
 self.x = x
 self.y = y

 def __iter__(self):
 return (n for n in (self.x, self.y))

我們把 x 和 y 變成了只讀特性。這是一項(xiàng)重大重構(gòu),但是 Vector2d 的接口基本沒變:用戶仍能讀取my_vector.x 和 my_vector.y。

class Vector2d:

 def __init__(self, x, y):
 self.__x = x
 self.__y = y

 @property
 def x(self):
 return self.__x

 @property
 def y(self):
 return self.__y

 def __iter__(self):
 return (i for i in (self.x, self.y))

Python喜歡序列

Python 數(shù)據(jù)模型的哲學(xué)是盡量支持基本協(xié)議。對序列來說,即便是最簡單的實(shí)現(xiàn),Python 也會(huì)力求做到最好。

下圖展示了定義為抽象基類的 Sequence 正式接口。

Sequence 抽象基類和 collections.abc 中相關(guān)抽象類的UML 類圖,箭頭由子類指向超類,以斜體顯示的是抽象方法

現(xiàn)在,看看下面🌰中的 Foo 類。它沒有繼承 abc.Sequence,而且只實(shí)現(xiàn)了序列協(xié)議的一個(gè)方法: __getitem__ (沒有實(shí)現(xiàn) __len__ 方法)。

>>> class Foo:
...   def __getitem__(self, pos):
...     return range(0, 30, 10)[pos]
...
>>> f = Foo()
>>> f[1]

>>> for i in f: print(i)
...



>>> 20 in f
True
>>> 15 in f
False

雖然沒有 __iter__ 方法,但是 Foo 實(shí)例是可迭代的對象,因?yàn)榘l(fā)現(xiàn)有__getitem__ 方法時(shí),Python 會(huì)調(diào)用它,傳入從 0 開始的整數(shù)索引,嘗試迭代對象(這是一種后備機(jī)制)。盡管沒有實(shí)現(xiàn) __contains__ 方法,但是 Python 足夠智能,能迭代 Foo 實(shí)例,因此也能使用 in 運(yùn)算符:Python 會(huì)做全面檢查,看看有沒有指定的元素。

綜上,鑒于序列協(xié)議的重要性,如果沒有 __iter__ 和 __contains__方法,Python 會(huì)調(diào)用 __getitem__ 方法,設(shè)法讓迭代和 in 運(yùn)算符可用。

下面的FrenchDeck 類也沒有繼承 abc.Sequence,但是實(shí)現(xiàn)了序列協(xié)議的兩個(gè)方法:__getitem__ 和 __len__。

class FrenchDeck:
 ranks = [str(n) for n in range(2, 11)] + list('JQKA')
 suits = 'spades diamonds clubs hearts'.split()

 def __init__(self):
 self._cards = [Cards(rank, suit) for suit in self.suits
      for rank in self.ranks]

 def __len__(self):
 return len(self._cards)

 def __getitem__(self, pos):
 return self._cards[pos]

使用猴子補(bǔ)丁在運(yùn)行時(shí)實(shí)現(xiàn)協(xié)議

FrenchDeck 類有個(gè)重大缺陷:無法洗牌。如果 FrenchDeck 實(shí)例的行為像序列,那么它就不需要 shuffle 方法,因?yàn)橐呀?jīng)有 random.shuffle 函數(shù)可用,文檔中說它的作用是“就地打亂序x”(https://docs.python.org/3/library/random.html#random.shuffle)。

標(biāo)準(zhǔn)庫中的 random.shuffle 函數(shù)用法如下:

>>> from random import shuffle
>>> my_list = list(range(1, 11))
>>> shuffle(my_list)
>>> my_list
[5, 7, 9, 2, 10, 1, 8, 6, 4, 3]

然而,如果嘗試打亂 FrenchDeck 實(shí)例,會(huì)出現(xiàn)異常,如下面的 🌰 所示。

Traceback (most recent call last):
 File "/Users/demon/PycharmProjects/FluentPython/接口:從協(xié)議到抽象基類/FrenchDeck.py", line 37, in <module>
 shuffle(deck)
 File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/random.py", line 274, in shuffle
 x[i], x[j] = x[j], x[i]
TypeError: 'FrenchDeck' object does not support item assignment  

錯(cuò)誤消息相當(dāng)明確,“'FrenchDeck' object does not support itemassignment”('FrenchDeck' 對象不支持為元素賦值)。這個(gè)問題的原因是,shuffle 函數(shù)要調(diào)換集合中元素的位置,而 FrenchDeck 只實(shí)現(xiàn)了不可變的序列協(xié)議??勺兊男蛄羞€必須提供 __setitem__ 方法。

解決辦法為FrenchDeck 打猴子補(bǔ)丁,把它變成可變的,讓random.shuffle 函數(shù)能處理

from collections import namedtuple
from random import shuffle

Cards = namedtuple('Cards', ['rank', 'suit'])

class FrenchDeck:
 ranks = [str(n) for n in range(2, 11)] + list('JQKA')
 suits = 'spades diamonds clubs hearts'.split()

 def __init__(self):
 self._cards = [Cards(rank, suit) for suit in self.suits
      for rank in self.ranks]

 def __len__(self):   #獲取長度的len
 return len(self._cards)

 def __getitem__(self, position): #能夠支持切片取值的處理
 return self._cards[position]


deck = FrenchDeck()    #實(shí)例化

def set_card(deck, position, card):  #猴子不定,其實(shí)就是啟動(dòng)調(diào)用內(nèi)部__setitem__設(shè)置值得外部函數(shù)
 deck._cards[position] = card

FrenchDeck.__setitem__ = set_card  #把猴子補(bǔ)丁傳遞給內(nèi)部的魔術(shù)方法
shuffle(deck)    #打亂洗牌的序列
print(deck[:5])    #獲取前五個(gè)卡牌的值

以上代碼的執(zhí)行結(jié)果為:

[Cards(rank='K', suit='diamonds'), Cards(rank='4', suit='spades'), Cards(rank='A', suit='clubs'), Cards(rank='K', suit='spades'), Cards(rank='6', suit='clubs')]  

這里的關(guān)鍵是,set_card 函數(shù)要知道 deck 對象有一個(gè)名為 _cards 的屬性,而且 _cards 的值必須是可變序列。然后,我們把 set_card 函數(shù)賦值給特殊方法 __setitem__,從而把它依附到 FrenchDeck 類上。這種技術(shù)叫猴子補(bǔ)?。涸谶\(yùn)行時(shí)修改類或模塊,而不改動(dòng)源碼。猴子補(bǔ)丁很強(qiáng)大,但是打補(bǔ)丁的代碼與要打補(bǔ)丁的程序耦合十分緊密,而且往往要處理隱藏和沒有文檔的部分。

定義抽象基類的子類

在下面的🌰 中,我們明確把 FrenchDeck2 聲明為collections.MutableSequence 的子類。

frenchdeck2.py:FrenchDeck2,collections.MutableSequence的子類

import collections


Card = collections.namedtuple('Card', ['rank', 'suit'])


class FrenchDeck2(collections.MutableSequence):
 ranks = [str(i) for i in range(1, 11)] + list('JQKA')
 suits = 'spades diamonds clubs hearts'.split()

 def __init__(self):
 self._cards = [Card(rank, suit) for suit in self.suits
     for rank in self.ranks]

 def __len__(self):    #支持查看長度
 return len(self._cards)

 def __getitem__(self, position):  #支持切片
 return self._cards[position]

 def __setitem__(self, position, value):  #支持洗牌
 self._cards[position] = value

 def __delitem__(self, position):  #但是繼承MutableSequence的類必須實(shí)現(xiàn) __delitem__ 方法,這是MutableSequence 類的一個(gè)抽象方法。
 del self._cards[position]

 def insert(self, position, value):  #此外,還要實(shí)現(xiàn)insert方法,這是MutableSequence類的第三個(gè)抽象方法
 self._cards.insert(position, value)

Sequence 和 MutableSequence 抽象基類的方法不全是抽象的。

MutableSequence 抽象基類和 collections.abc 中它的超類的 UML 類圖(箭頭由子類指向祖先;以斜體顯示的名稱是抽象類和抽象方法)

FrenchDeck2 從 Sequence 繼承了幾個(gè)拿來即用的具體方法__contains__、__iter__、__reversed__、index 和count。FrenchDeck2 從MutableSequence 繼承了append、extend、pop、remove 和__iadd__。

標(biāo)準(zhǔn)庫中的抽象基類

從 Python 2.6 開始,標(biāo)準(zhǔn)庫提供了抽象基類。大多數(shù)抽象基類在collections.abc 模塊中定義,不過其他地方也有。例如,numbers和 io 包中有一些抽象基類。但是,collections.abc 中的抽象基類最常用。我們來看看這個(gè)模塊中有哪些抽象基類。

collections.abc模塊中的抽象基類

collections.abc 模塊中各個(gè)抽象基類的 UML 類圖

Iterable、Container 和 Sized

各個(gè)集合應(yīng)該繼承這三個(gè)抽象基類,或者至少實(shí)現(xiàn)兼容的協(xié)議。Iterable 通過 __iter__ 方法支持迭代,Container 通過__contains__ 方法支持 in 運(yùn)算符,Sized 通過 __len__ 方法支持len() 函數(shù)。

Sequence、Mapping 和 Set

這三個(gè)是主要的不可變集合類型,而且各自都有可變的子類

MappingView

在 Python 3 中,映射方法 .items()、.keys() 和 .values() 返回的對象分別是 ItemsView、KeysView 和 ValuesView 的實(shí)例。前兩個(gè)類還從 Set 類繼承了豐富的接口。

Callable 和 Hashable

這兩個(gè)抽象基類與集合沒有太大的關(guān)系,只不過因?yàn)閏ollections.abc 是標(biāo)準(zhǔn)庫中定義抽象基類的第一個(gè)模塊,而它們又太重要了,因此才把它們放到 collections.abc 模塊中。我從未見過Callable 或 Hashable 的子類。這兩個(gè)抽象基類的主要作用是為內(nèi)置函數(shù) isinstance 提供支持,以一種安全的方式判斷對象能不能調(diào)用或散列。

Iterator

注意它是 Iterable 的子類。繼 collections.abc 之后,標(biāo)準(zhǔn)庫中最有用的抽象基類包是numbers

抽象基類的數(shù)字塔

numbers 包(https://docs.python.org/3/library/numbers.html)定義的是“數(shù)字塔”(即各個(gè)抽象基類的層次結(jié)構(gòu)是線性的),其中 Number 是位于最頂端的超類,隨后是 Complex 子類,依次往下,最底端是 Integral類:

Number

Complex

Real

Rational

Integral

因此,如果想檢查一個(gè)數(shù)是不是整數(shù),可以使用 isinstance(x,numbers.Integral),這樣代碼就能接受 int、bool(int 的子類),或者外部庫使用 numbers 抽象基類注冊的其他類型。為了滿足檢查的需要,你或者你的 API 的用戶始終可以把兼容的類型注冊為numbers.Integral 的虛擬子類。

與之類似,如果一個(gè)值可能是浮點(diǎn)數(shù)類型,可以使用 isinstance(x,numbers.Real) 檢查。這樣代碼就能接受bool、int、float、fractions.Fraction,或者外部庫(如NumPy,它做了相應(yīng)的注冊)提供的非復(fù)數(shù)類型。

定義并使用一個(gè)抽象基類

為了證明有必要定義抽象基類,我們要在框架中找到使用它的場景。想象一下這個(gè)場景:你要在網(wǎng)站或移動(dòng)應(yīng)用中顯示隨機(jī)廣告,但是在整個(gè)廣告清單輪轉(zhuǎn)一遍之前,不重復(fù)顯示廣告。假設(shè)我們在構(gòu)建一個(gè)廣告管理框架,名為 ADAM。它的職責(zé)之一是,支持用戶提供隨機(jī)挑選的無重復(fù)類。 為了讓 ADAM 的用戶明確理解“隨機(jī)挑選的無重復(fù)”組件是什么意思,我們將定義一個(gè)抽象基類。

受到“?!焙汀瓣?duì)列”(以物體的排放方式說明抽象接口)啟發(fā),我將使用現(xiàn)實(shí)世界中的物品命名這個(gè)抽象基類:賓果機(jī)和彩票機(jī)是隨機(jī)從有限的集合中挑選物品的機(jī)器,選出的物品沒有重復(fù),直到選完為止。

我們把這個(gè)抽象基類命名為 Tombola,這是賓果機(jī)和打亂數(shù)字的滾動(dòng)容器的意大利名。

Tombola 抽象基類有四個(gè)方法,其中兩個(gè)是抽象方法。

.load(...):把元素放入容器。

.pick():從容器中隨機(jī)拿出一個(gè)元素,返回選中的元素

另外兩個(gè)是具體方法。

.loaded():如果容器中至少有一個(gè)元素,返回 True。

.inspect():返回一個(gè)有序元組,由容器中的現(xiàn)有元素構(gòu)成,不會(huì)修改容器的內(nèi)容(內(nèi)部的順序不保留)。

展示了 Tombola 抽象基類和三個(gè)具體實(shí)現(xiàn)。

一個(gè)抽象基類和三個(gè)子類的 UML 類圖。根據(jù) UML 的約定,Tombola 抽象基類和它的抽象方法使用斜體。虛線箭頭用于表示接口實(shí)現(xiàn),這里它表示 TomboList 是 Tombola 的虛擬子類,因?yàn)門omboList 是注冊的

import abc


class Tombola(abc.ABC):      #自己定義的抽象基類要繼承abc.ABC

 @abc.abstractmethod
 def load(self, iterable):     #抽象方法使用@abstractmethod裝飾器標(biāo)記,而且定義體中通常只有文檔字符串
 """從可迭代對象中添加元素"""

 @abc.abstractmethod
 def pick(self):      #根據(jù)文檔字符串,如果沒有元素可選,應(yīng)該拋出LookupError
 """隨機(jī)刪除元素,然后返回
  如果實(shí)例為空,這個(gè)方法應(yīng)該拋出'LookupError'
 """

 def loaded(self):      #抽象基類可以包含具體方法
 """如果至少有一個(gè)元素,返回`True`,否則返回`False`。"""
 return bool(self.inspect())

 def inspect(self):
 """返回一個(gè)有序元組,由當(dāng)前元素構(gòu)成。"""
 items = []
 while True:
  try:
  items.append(self.pick())   
  except LookupError:
  break
 self.load(items)     #使用 .load(...)把所有元素放回去
 return tuple(sorted(items))    #返回排序好的items攻loaded調(diào)用

選擇使用 LookupError 異常的原因是,在 Python 的異常層次關(guān)系中,它與 IndexError 和 KeyError 有關(guān),這兩個(gè)是具體實(shí)現(xiàn) Tombola的數(shù)據(jù)結(jié)構(gòu)最有可能拋出的異常。據(jù)此,實(shí)現(xiàn)代碼可能會(huì)拋出LookupError、IndexError 或 KeyError 異常。

異常類的部分層次結(jié)構(gòu)

BaseException
├── SystemExit
├── KeyboardInterrupt
├── GeneratorExit
└── Exception
 ├── StopIteration
 ├── ArithmeticError
 │ ├── FloatingPointError
 │ ├── OverflowError
 │ └── ZeroDivisionError
 ├── AssertionError
 ├── AttributeError
 ├── BufferError
 ├── EOFError
 ├── ImportError
 ├── LookupError #我們在 Tombola.inspect 方法中處理的是 LookupError 異常 
 │ ├── IndexError #IndexError 是 LookupError 的子類,嘗試從序列中獲取索引超過最后位置的元素時(shí)拋出 
 │ └── KeyError #使用不存在的鍵從映射中獲取元素時(shí),拋出 KeyError 異常
 ├── MemoryError
 ... etc.

我們自己定義的 Tombola 抽象基類完成了。為了一睹抽象基類對接口所做的檢查,下面我們嘗試使用一個(gè)有缺陷的實(shí)現(xiàn)來糊弄 Tombola,如下面的 🌰 所示

不符合 Tombola 要求的子類無法蒙混過關(guān)

>>> from tombola import Tombola
>>> class Fake(Tombola):               # 把Fake聲明為Tombole的子類,繼承抽象類
...  def pick(self):
...  return 13
...
>>> Fake                         # 創(chuàng)建Fake類,目前木有毛線問題~
<class '__main__.Fake'>
>>> f = Fake()                     # 報(bào)錯(cuò)了,Python認(rèn)為Fake類是抽象類,因?yàn)闆]有實(shí)現(xiàn)load方法
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Fake with abstract methods load

抽象基類句法詳解

聲明抽象基類最簡單的方式是繼承 abc.ABC 或其他抽象基類。

然而,abc.ABC 是 Python 3.4 新增的類,因此如果你使用的是舊版Python,那么無法繼承現(xiàn)有的抽象基類。此時(shí),必須在 class 語句中使用 metaclass= 關(guān)鍵字,把值設(shè)為 abc.ABCMeta(不是 abc.ABC)。在下面的🌰 ,可以寫成:

class Tombola(metaclass=abc.ABCMeta):
 # ...

metaclass= 關(guān)鍵字參數(shù)是 Python 3 引入的。在 Python 2 中必須使用__metaclass__ 類屬性:

class Tombola(object): # 這是Python 2!??!
 __metaclass__ = abc.ABCMeta
 # ...  

除了 @abstractmethod 之外,abc 模塊還定義了@abstractclassmethod、@abstractstaticmethod 和@abstractproperty 三個(gè)裝飾器。然而,后三個(gè)裝飾器從 Python 3.3起廢棄了,因?yàn)檠b飾器可以在 @abstractmethod 上堆疊,那三個(gè)就顯得多余了。例如,聲明抽象類方法的推薦方式是:

class MyABC(abc.ABC):
 @classmethod
 @abc.abstractmethod
 def an_abstract_classmethod(cls, ...):
 pass 

定義Tombola抽象基類的子類

定義好 Tombola 抽象基類之后,我們要開發(fā)兩個(gè)具體子類,滿足Tombola 規(guī)定的接口。

下面的🌰 中的 BingoCage 類,使用了更好的隨機(jī)發(fā)生器。 BingoCage 實(shí)現(xiàn)了所需的抽象方法 load 和 pick,從 Tombola 中繼承了 loaded 方法,覆蓋了 inspect 方法,還增加了__call__ 方法。

import random
import abc


class Tombola(abc.ABC):      #自己定義的抽象基類要繼承abc.ABC

 @abc.abstractmethod
 def load(self, iterable):     #抽象方法使用@abstractmethod裝飾器標(biāo)記,而且定義體中通常只有文檔字符串
 """從可迭代對象中添加元素"""

 @abc.abstractmethod
 def pick(self):      #根據(jù)文檔字符串,如果沒有元素可選,應(yīng)該拋出LookupError
 """隨機(jī)刪除元素,然后返回
  如果實(shí)例為空,這個(gè)方法應(yīng)該拋出'LookupError'
 """

 def loaded(self):      #抽象基類可以包含具體方法
 """如果至少有一個(gè)元素,返回`True`,否則返回`False`。"""
 return bool(self.inspect())

 def inspect(self):
 """返回一個(gè)有序元組,由當(dāng)前元素構(gòu)成。"""
 items = []
 while True:
  try:
  items.append(self.pick())
  except LookupError:
  break
 self.load(items)     #使用 .load(...)把所有元素放回去
 return tuple(sorted(items))    #返回排序好的items攻loaded調(diào)用


#下面的代碼應(yīng)該單端放到一個(gè)py文件中,為了省事,就不在單獨(dú)放到一個(gè)模塊里面導(dǎo)入了~

class BigoCage(Tombola):     #明確指定BingoCage類擴(kuò)展Tombola類

 def __init__(self, items):
 self._randomizer = random.SystemRandom()  #假設(shè)我們將在線上游戲中使用這個(gè)。random.SystemRandom使用os.urandom(...) 函數(shù)實(shí)現(xiàn)randomAPI
 self._items = []
 self.load(items)     #委托.load(...)方法實(shí)現(xiàn)初始加載

 def load(self, items):
 self._items.extend(items)    #如果通過load方法傳遞一個(gè)可迭代的對象進(jìn)來,可以擴(kuò)展到以后的self._items的列表中
 self._randomizer.shuffle(self._items)   #沒有使用random.shuffle而是使用了SystemRandom中的shuffle方法

 def pick(self):
 try:
  return self._items.pop()
 except IndexError:
  raise LookupError('pick from empty BingoCage')

 def __call__(self):
 self.pick()

b = BigoCage(range(10))
print(b.pick())

下面是 Tombola 接口的另一種實(shí)現(xiàn),雖然與之前不同,但完全有效。LotteryBlower 打亂“數(shù)字球”后沒有取出最后一個(gè),而是取出一個(gè)隨機(jī)位置上的球。

lotto.py:LotteryBlower 是 Tombola 的具體子類,覆蓋了繼承的 inspect 和 loaded 方法

import random

from tombola import Tombola


class LotteryBlower(Tombola):

 def __init__(self, iterable):
 self._balls = list(iterable)  #創(chuàng)建一個(gè)副本

 def load(self, iterbale):
 self._balls.extend(iterbale)  #把一個(gè)可迭代的對象添加到列表中

 def pick(self):
 try:
  position = random.randrange(len(self._balls)) #獲取一個(gè)隨機(jī)數(shù)
 except ValueError:
  raise LookupError('pick from empty LotteryBlower')
 return self._balls.pop(position)  #刪除列表中通過列表長度獲取的隨機(jī)數(shù)位置的索引值

 def loaded(self):
 return bool(self._balls)

 def inspect(self):
 return tuple(sorted(self._balls))

以上這篇python 接口_從協(xié)議到抽象基類詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python 實(shí)現(xiàn)自動(dòng)完成A4標(biāo)簽排版打印功能

    Python 實(shí)現(xiàn)自動(dòng)完成A4標(biāo)簽排版打印功能

    這篇文章主要介紹了Python 實(shí)現(xiàn)自動(dòng)完成A4標(biāo)簽排版打印功能,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • python3 模擬登錄v2ex實(shí)例講解

    python3 模擬登錄v2ex實(shí)例講解

    下面小編就為大家?guī)硪黄猵ython3 模擬登錄v2ex實(shí)例講解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-07-07
  • python連接sql?server數(shù)據(jù)庫的方法實(shí)戰(zhàn)

    python連接sql?server數(shù)據(jù)庫的方法實(shí)戰(zhàn)

    當(dāng)我們用Python來編寫網(wǎng)站,必須要能夠通過python操作數(shù)據(jù)庫,下面這篇文章主要給大家介紹了關(guān)于python連接sql?server數(shù)據(jù)庫的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • python數(shù)據(jù)封裝json格式數(shù)據(jù)

    python數(shù)據(jù)封裝json格式數(shù)據(jù)

    本次內(nèi)容是小編在網(wǎng)上整理的關(guān)于如何python數(shù)據(jù)封裝json格式的內(nèi)容總結(jié),有興趣的讀者們參考下。
    2018-03-03
  • 在python項(xiàng)目的docker鏡像里如何使用pdm管理依賴

    在python項(xiàng)目的docker鏡像里如何使用pdm管理依賴

    在 DjangoStarter 項(xiàng)目中,我已經(jīng)使用 pdm 作為默認(rèn)的包管理器,不再直接使用 pip,所以部署的時(shí)候 dockerfile 和 docker-compose 配置需要修改一下,這篇文章主要介紹了在python項(xiàng)目的docker鏡像里使用pdm管理依賴,需要的朋友可以參考下
    2024-08-08
  • Python?中如何將十六進(jìn)制轉(zhuǎn)換為?Base64

    Python?中如何將十六進(jìn)制轉(zhuǎn)換為?Base64

    本篇文章將介紹在?Python?中將?hex?轉(zhuǎn)換為?base64?的方法,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06
  • 關(guān)于Python 3中print函數(shù)的換行詳解

    關(guān)于Python 3中print函數(shù)的換行詳解

    最近在學(xué)習(xí)python3,發(fā)現(xiàn)了一個(gè)問題想著總結(jié)出來,所以下面這篇文章主要給大家介紹了關(guān)于Python 3中print函數(shù)換行的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對需要的朋友們具有一定的參考學(xué)習(xí)價(jià)值,感興趣的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • 對Python 窗體(tkinter)文本編輯器(Text)詳解

    對Python 窗體(tkinter)文本編輯器(Text)詳解

    今天小編就為大家分享一篇對Python 窗體(tkinter)文本編輯器(Text)詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-10-10
  • python中如何進(jìn)行連乘計(jì)算

    python中如何進(jìn)行連乘計(jì)算

    在本篇文章里小編給大家分享的是關(guān)于python連乘計(jì)算的代碼,有興趣的朋友們可以參考學(xué)習(xí)下。
    2020-05-05
  • Python OpenCV簡單的繪圖函數(shù)使用教程

    Python OpenCV簡單的繪圖函數(shù)使用教程

    本文主要為大家介紹了OpenCV中一些簡單的繪圖函數(shù)的使用教程,文中的示例代碼講解詳細(xì),對我們了解OpenCV有一定的幫助,感興趣的可以學(xué)習(xí)一下
    2022-01-01

最新評論