DataSource
模块中的numpy.lib._datasource
类有一个简短的实例方法_isurl(self,path)
,用于测试path
是否为净位置。它不以任何方式使用实例及其成员
确实(在python 3.3中)它可以在没有实际创建实例的情况下使用:
DataSource._isurl(None,path)
然而,正如我所看到的,这是静态方法的典型情况(甚至是在任何类之外定义的常规函数)。将它作为实例方法编写是否有任何好处?
答案 0 :(得分:1)
我非常有信心因性能原因而没有这样做:
import sys
if sys.version_info[0] >= 3:
from urllib.parse import urlparse
else:
from urlparse import urlparse
class DataSource(object):
def _isurl(self, path):
scheme, netloc, upath, uparams, uquery, ufrag = urlparse(path)
return bool(scheme and netloc)
@staticmethod
def _isurl_staticmeth(path):
scheme, netloc, upath, uparams, uquery, ufrag = urlparse(path)
return bool(scheme and netloc)
时序:
In [1]: ds = DataSource()
In [2]: %timeit ds._isurl_staticmeth('http://www.google.com')
The slowest run took 14.76 times longer than the fastest. This could mean that an intermediate result is being cached
100000 loops, best of 3: 2.25 µs per loop
In [3]: %timeit ds._isurl('http://www.google.com')
The slowest run took 12.99 times longer than the fastest. This could mean that an intermediate result is being cached
100000 loops, best of 3: 2.31 µs per loop
实际上,两种方法都产生几乎相同的字节码:
In [4]: import dis
In [5]: dis.dis(ds._isurl)
9 0 LOAD_GLOBAL 0 (urlparse)
3 LOAD_FAST 1 (path)
6 CALL_FUNCTION 1
9 UNPACK_SEQUENCE 6
12 STORE_FAST 2 (scheme)
15 STORE_FAST 3 (netloc)
18 STORE_FAST 4 (upath)
21 STORE_FAST 5 (uparams)
24 STORE_FAST 6 (uquery)
27 STORE_FAST 7 (ufrag)
10 30 LOAD_GLOBAL 1 (bool)
33 LOAD_FAST 2 (scheme)
36 JUMP_IF_FALSE_OR_POP 42
39 LOAD_FAST 3 (netloc)
>> 42 CALL_FUNCTION 1
45 RETURN_VALUE
In [6]: dis.dis(ds._isurl_staticmeth)
14 0 LOAD_GLOBAL 0 (urlparse)
3 LOAD_FAST 0 (path)
6 CALL_FUNCTION 1
9 UNPACK_SEQUENCE 6
12 STORE_FAST 1 (scheme)
15 STORE_FAST 2 (netloc)
18 STORE_FAST 3 (upath)
21 STORE_FAST 4 (uparams)
24 STORE_FAST 5 (uquery)
27 STORE_FAST 6 (ufrag)
15 30 LOAD_GLOBAL 1 (bool)
33 LOAD_FAST 1 (scheme)
36 JUMP_IF_FALSE_OR_POP 42
39 LOAD_FAST 2 (netloc)
>> 42 CALL_FUNCTION 1
45 RETURN_VALUE
无论哪种方式,_isurl
似乎都不太可能在性能危急的情况下使用。
我不能代表那些笨拙的开发者,但我想不出任何特别的理由,为什么不让_isurl
成为静态方法而不是实例方法。如果我从头开始设计一个类似的类,那么我可能会使它成为静态方法或只是一个普通的旧模块函数。