7.9 将�方法的类转�为函数¶
问题¶
ä½ æœ‰ä¸€ä¸ªé™¤ __init__() 方法外å�ªå®šä¹‰äº†ä¸€ä¸ªæ–¹æ³•的类。为了简化代ç �ï¼Œä½ æƒ³å°†å®ƒè½¬æ�¢æˆ�一个函数。
解决方案¶
大多数情况下,å�¯ä»¥ä½¿ç”¨é—包æ�¥å°†å�•个方法的类转æ�¢æˆ�函数。 举个例å�,下é�¢ç¤ºä¾‹ä¸çš„ç±»å…�è®¸ä½¿ç”¨è€…æ ¹æ�®æŸ�个模æ�¿æ–¹æ¡ˆæ�¥èŽ·å�–到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'))
这个类�以被一个更简�的函数�代替:
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'))
讨论¶
å¤§éƒ¨åˆ†æƒ…å†µä¸‹ï¼Œä½ æ‹¥æœ‰ä¸€ä¸ªå�•æ–¹æ³•ç±»çš„åŽŸå› æ˜¯éœ€è¦�å˜å‚¨æŸ�些é¢�外的状æ€�æ�¥ç»™æ–¹æ³•使用。 比如,定义UrlTemplate类的唯一目的就是先在æŸ�个地方å˜å‚¨æ¨¡æ�¿å€¼ï¼Œä»¥ä¾¿å°†æ�¥å�¯ä»¥åœ¨open()方法ä¸ä½¿ç”¨ã€‚
使用一个内部函数或者é—包的方案通常会更优雅一些。简å�•æ�¥è®²ï¼Œä¸€ä¸ªé—包就是一个函数,
å�ªä¸�过在函数内部带上了一个é¢�外的å�˜é‡�环境。é—包关键特点就是它会记ä½�自己被定义时的环境。
å› æ¤ï¼Œåœ¨æˆ‘们的解决方案ä¸ï¼Œopener() 函数记ä½�了 template å�‚数的值,并在接下æ�¥çš„调用ä¸ä½¿ç”¨å®ƒã€‚
任何时候å�ªè¦�ä½ ç¢°åˆ°éœ€è¦�ç»™æŸ�ä¸ªå‡½æ•°å¢žåŠ é¢�外的状æ€�ä¿¡æ�¯çš„问题,都å�¯ä»¥è€ƒè™‘使用é—包。 ç›¸æ¯”å°†ä½ çš„å‡½æ•°è½¬æ�¢æˆ�一个类而言,é—包通常是一ç§�æ›´åŠ ç®€æ´�和优雅的方案。