小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

一招快速重構(gòu) Python 代碼

 進擊的Grey 2023-11-27 發(fā)布于廣東
代碼重構(gòu)處理的不好,將會是意見非常令人頭疼的事情,因為有可能牽涉到許多的團隊和大量的代碼庫修改。那么如何高效、快速地進行代碼重構(gòu),就是Python程序員值得掌握的技巧。
本分介紹的是通過Python中的@property裝飾器,快速進行代碼重構(gòu)的一個例子,供大家參考。

從前,Python程序員Alice要打算創(chuàng)建一個代表金錢的類。她的第一個實現(xiàn)形式大概是下面這樣:

# 以美元為基礎(chǔ)貨幣的Money類的首個版本
class Money:
def __init__(self, dollars, cents):
self.dollars = dollars
self.cents = cents
# 還有其他一些方法,我們暫時不必理會

這個類后來被打包到一個Python庫里,并且慢慢地被許多不同的應(yīng)用使用。舉個例子,另一個團隊中的Python程序員Bob是這樣使用Money類的:

money = Money(27, 12)
message = "I have {:d} dollars and {:d} cents."
print(message.format(money.dollars, money.cents))
# "I have 27 dollars and 12 cents."
money.dollars += 2
money.cents += 20
print(message.format(money.dollars, money.cents))
# "I have 29 dollars and 32 cents."

這樣使用并沒有錯,但是卻出現(xiàn)了代碼可維護性的問題。你發(fā)現(xiàn)了嗎?

幾個月或是幾年之后。Alice想要重構(gòu)Money類的內(nèi)部實現(xiàn),不再記錄美元和美分,而是僅僅記錄美分,因為這樣做可以讓某些操作簡單很多。下面是她很可能會作的修改:

# Money類的第二個版本
class Money:
def __init__(self, dollars, cents):
self.total_cents = dollars * 100 + cents

這一修改帶來一個后果:引用Money類的每一行代碼都必須要調(diào)整。有時候很幸運,你就是所有這些代碼的維護者,只需要自己直接重構(gòu)即可。但是Alice的情況就沒有這么好了;許多團隊都復(fù)用了她的代碼。因此,她需要協(xié)調(diào)他們的代碼庫與自己的修改保持一致,也許甚至要經(jīng)歷一段特別痛苦、漫長的正式棄用過程(deprecation process)。

幸運的是,Alice知道一種更好的解決辦法,可以避免這個令人頭疼的局面出現(xiàn):使用Python內(nèi)建的property裝飾器。@property一般應(yīng)用在Python方法上,可以有效地將屬性訪問(attribute access)變成方法調(diào)用(method call)。舉個例子,暫時將Money類拋至一邊,假設(shè)有一個代表人類的Person類(class):

class Person:
def __init__(self, first, last):
self.first = first
self.last = last
@property
def full_name(self):
return '{} {}'.format(self.first, self.last)

代碼樣式不同,是因為之前用的工具出問題了?!狤arlGrey

請注意full_name方法。除了在def語句上方裝飾了@property之外,該方法的聲明沒有什么不同的地方。但是,這卻改變了Person對象的運作方式:

>>> buddy = Person('Jonathan', 'Doe')
>>> buddy.full_name
'Jonathan Doe'

我們發(fā)現(xiàn),盡管full_name被定義為一個方法,但卻可以通過變量屬性的方式訪問。在最后一行代碼中沒有()操作符;我并沒有調(diào)用full_name方法。我們所做的,可以說是創(chuàng)建了某種動態(tài)屬性。

回到本文中的Money類,Alice對它作了如下修改:

# Money類的最終版本
class Money:
def __init__(self, dollars, cents):
self.total_cents = dollars * 100 + cents
# Getter and setter for dollars...
@property
def dollars(self):
return self.total_cents // 100;
@dollars.setter
def dollars(self, new_dollars):
self.total_cents = 100 * new_dollars + self.cents
# And the getter and setter for cents.
@property
def cents(self):
return self.total_cents % 100;
@cents.setter
def cents(self, new_cents):
self.total_cents = 100 * self.dollars + new_cents

除了使用@property裝飾器定義了dollars屬性的getter外,Alice還利用@dollars.setter創(chuàng)建了一個setter。Alice還對cents`屬性作了類似處理。

那么現(xiàn)在,Bob的代碼要做哪些相應(yīng)的修改呢?根本不用改!

# 他的代碼完全沒有變動,但是卻可以正常調(diào)用Money類。
money = Money(27, 12)
message = "I have {:d} dollars and {:d} cents."
print(message.format(money.dollars, money.cents))
# "I have 27 dollars and 12 cents."
money.dollars += 2
money.cents += 20
print(message.format(money.dollars, money.cents))
# "I have 29 dollars and 32 cents."# 代碼邏輯也沒有問題。
money.cents += 112
print(message.format(money.dollars, money.cents))
# "I have 30 dollars and 44 cents."

事實上,所有使用了Money類的代碼都不需要進行修改。Bob不知道或根本不在乎Alice去除了類中的dollars和cents屬性:他的代碼還是和以前一樣正常執(zhí)行。唯一修改過的代碼就是Money類本身。

正是由于Python中處理裝飾器的方式,你可以在類中自由使用簡單的屬性。如果你所寫的類改變了管理狀態(tài)的方法,你可以自信地通過@property裝飾器對這個類(且只有這個類)進行修改。這是一個共贏的方法!相反,在Java等語言中,程序員必須主動去定義訪問屬性的方法(例如getDollars或setCents)。

最后要提示大家:

這種方法對于那些被其他程序員和團隊復(fù)用的代碼最為重要。假設(shè)僅僅是在你自己一個維護的應(yīng)用中創(chuàng)建一個類似Money的類,那么如果你改變了Money的接口,你只需要重構(gòu)自己的代碼就可以。這種情況下,你沒有必要像上面說的那樣使用@property裝飾器。

原文:http:///python-properties-refactoring/

譯文:http:///article/python-properties-refactoring/

你是怎樣重構(gòu)Python代碼的?

歡迎留言和我們分享

印度小伙寫了套深度學(xué)習教程,Github上星標已經(jīng)5000+

上百個數(shù)據(jù)文件合并,只能手動復(fù)制粘貼?教你一招十秒搞定!

一個提升圖像識別準確率的精妙技巧

一文讀懂:從 Python 打包到 CLI 工具

如何使用 Python 進行時間序列預(yù)測?

美亞Kindle排名第一的Python 3入門書,火遍了整個編程圈

十分鐘搭建私有 Jupyter Notebook 服務(wù)器

使用 Python 制作屬于自己的 PDF 電子書

12步輕松搞定Python裝飾器

200 行代碼實現(xiàn) 2048 游戲

    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多