创建一个Python类方法
我已经熟悉了这个概念,特别是通过观看Raymond Hettinger的优秀视频并阅读接受的答案,我想知道我错了什么。
class ReadHTML(object):
def __init__(self, url):
page = urlopen(url).read()
self.page = page
@classmethod
def from_file(cls, path):
page = open(path).read()
return cls(page)
这工作
r = ReadHTML('http://example.com')
print r.page
而这不是
r = ReadHTML.from_file('example.html')
print r.page
它会抛出一个错误,就像我试图“urlopen”一个文件一样:
File "/usr/lib/python2.7/urllib2.py", line 258, in get_type
raise ValueError, "unknown url type: %s" % self.__original
ValueError: unknown url type: <!doctype html>
你能看到有什么问题吗?
当您调用cls(page)
时,您仍然在调用类初始化程序ReadHTML.__init__()
cls(page)
; 该调用与调用ReadHTML(page)
没有区别,您只是使用了不同的引用。 这个方法只接受一个url
参数,代码将其传递给urlopen()
。
调整您的ReadHTML.__init__()
方法来处理被传递的页面而不是URL:
class ReadHTML(object):
def __init__(self, url=None, page=None):
if url is not None:
page = urlopen(url).read()
self.page = page
@classmethod
def from_file(cls, path):
page = open(path).read()
return cls(page=page)
现在代码支持两个路径来生成一个实例。
from_file
打开页面,但是你的__init__()
构造函数也是如此,所以如果你使用ReadHTML.from_file('example.html')
,你基本上是这样做的:
page = urlopen(open('example.html').read()).read()
就个人而言,我更喜欢Martijn的解决方案,为了语义清晰,但这里有一个选择:
class ReadHTML(object):
def __init__(self, url, opener=urlopen):
self.page = opener(url).read()
@classmethod
def from_file(cls, path):
return cls(path, opener=open)
这种解决方案是有利的,因为它使您能够定义任意开启者(例如,打开存储在数据库中的文件)。
我不是可选参数的重要粉丝。 我会这样做,以便默认构造函数接受一个字符串,我将不得不分开替代构造函数来处理文件名和URL。
我还修改了文件名构造函数以明确关闭文件。
class ReadHTML(object):
def __init__(self, page):
self.page = page
@classmethod
def from_filename(cls, path):
with open(path) as f:
page = f.read()
return cls(page)
@classmethod
def from_url(cls, url):
page = urlopen(url).read()
return cls(page)
作为一个方面说明,我相信urllib / urllib2支持file://,所以你完全不需要文件名构造函数(但我仍然相信它很好)。
链接地址: http://www.djcxy.com/p/54281.html上一篇: Creating a Python classmethod
下一篇: Python saying I'm passing in too many parameters to my function?