我无法理解为什么该类对象不使用我的 init 参数。这是python 3.6。
在一个文件中,我导入一个网络爬虫并将kwargs传递到其中:
import metacrawler as mc
mc.crawlwrapper(url=archive_url, archive_org=True, index_pages=True, depth_limit=2, fileroot='content/')
调试:是的,此时True参数定义为True
。
{'archive_org': True}
进入创建类实例的中间函数。这是介于中间的函数,用于解析从第一个函数到Crawler的所有内容:
def crawlwrapper(**kw):
fileroot = kw.get('fileroot','')
url = kw['url']
print('DEBUG(pre):{0}'.format(kw))
depth_limit = kw.get('depth_limit',3)
confine_prefix= kw.get('confine_prefix') # use to make archive.org not follow external links
archive_org = kw.get('archive_org',False) # special urlparse rules apply
exclude=kw.get('exclude',[])
print_pov=kw.get('print_pov',False)
index_pages = kw.get('index_pages')
print('DEBUG(post): depth_limit, confine_prefix, index_pages, archive_org {0}'.format([depth_limit, confine_prefix, index_pages, archive_org]))
crawler = Crawler(url, depth_limit, confine_prefix, exclude, index_pages, print_pov, archive_org)
crawler.crawl()
这里是Crawler
,它从crawlwrapper(** kw)函数接收kwarg:
class Crawler(object):
##BUG: for some reason, at some point, the init defaults don't get overridden when instatiated.
def __init__(self, url, depth_limit, confine=None, exclude=[], locked=True, filter_seen=True, index_pages=True, print_pov=False, archive_org=None):
print('depth_limit {0}, confine {1}, index_pages {2}, archive_org {3}'.format(depth_limit, confine, index_pages, archive_org))
调试:这是crawler.crawl()类方法中收到的内容:
depth_limit 2, confine http://www.cfu.or.ug, index_pages True, archive_org None
是否注意到achive_org从True
更改为None
?
为什么Crawler没有收到我的archive_org = True参数?
答案 0 :(得分:2)
这是因为当您编写Class(a, b)
时,它会将a
和b
的 values 传递给该类中定义为前两个名称的任何名称(或功能)。
但是当您说Class(a=a, b=b)
时,您是说“在Class.__init__
设置为a
并将a (from my scope)
设置为b
的情况下呼叫b (from my scope)
您在第一次通话中写的内容等同于crawler = Crawler(root=url, depth_limit=depth_limit, confine=confine_prefix, exclude=exclude, locked=index_pages, filter_seen=print_pov, index_pages=archive_org, print_pov=False, archive_org=None)
。
换句话说,调用者的名称空间/范围和被调用的函数/方法的签名之间没有隐式关系。除非您使用关键字参数(a=a
),否则参数是按位置分配的。
Python 3添加了对仅关键字参数的支持,这可能有助于防止这种情况。您是否这样定义了Crawler.__init__
:
def __init__(self, root, depth_limit, *, confine=None, exclude=[], locked=True, filter_seen=True, index_pages=True, print_pov=False, archive_org=None)
*
表示无法在位置上指定其余参数,而必须用名称表示。
老实说,直到我得到提示为止,我也为这个问题感到困惑。