7.9 將單方法的類轉換為函數(shù)

2018-02-24 15:26 更新

問題

你有一個除 __init__() 方法外只定義了一個方法的類。為了簡化代碼,你想將它轉換成一個函數(shù)。

解決方案

大多數(shù)情況下,可以使用閉包來將單個方法的類轉換成函數(shù)。舉個例子,下面示例中的類允許使用者根據(jù)某個模板方案來獲取到URL鏈接地址。

from urllib.request import urlopen

class UrlTemplate:
    def __init__(self, template):
        self.template = template

    def open(self, **kwargs):
        return urlopen(self.template.format_map(kwargs))

# Example use. Download stock data from yahoo
yahoo = UrlTemplate('http://finance.yahoo.com/d/quotes.csv?s={names}&f={fields}')
for line in yahoo.open(names='IBM,AAPL,FB', fields='sl1c1v'):
    print(line.decode('utf-8'))

這個類可以被一個更簡單的函數(shù)來代替:

def urltemplate(template):
    def opener(**kwargs):
        return urlopen(template.format_map(kwargs))
    return opener

# Example use
yahoo = urltemplate('http://finance.yahoo.com/d/quotes.csv?s={names}&f={fields}')
for line in yahoo(names='IBM,AAPL,FB', fields='sl1c1v'):
    print(line.decode('utf-8'))

討論

大部分情況下,你擁有一個單方法類的原因是需要存儲某些額外的狀態(tài)來給方法使用。比如,定義UrlTemplate類的唯一目的就是先在某個地方存儲模板值,以便將來可以在open()方法中使用。

使用一個內部函數(shù)或者閉包的方案通常會更優(yōu)雅一些。簡單來講,一個閉包就是一個函數(shù),只不過在函數(shù)內部帶上了一個額外的變量環(huán)境。閉包關鍵特點就是它會記住自己被定義時的環(huán)境。因此,在我們的解決方案中,opener() 函數(shù)記住了 template 參數(shù)的值,并在接下來的調用中使用它。

任何時候只要你碰到需要給某個函數(shù)增加額外的狀態(tài)信息的問題,都可以考慮使用閉包。相比將你的函數(shù)轉換成一個類而言,閉包通常是一種更加簡潔和優(yōu)雅的方案。

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號