代码之家  ›  专栏  ›  技术社区  ›  Marc Maxmeister

忽略实例化过程中传入类的参数/kwargs

  •  1
  • Marc Maxmeister  · 技术社区  · 6 年前

    我很难理解为什么这个类对象 初始 参数。这是Python3.6。

    在一个文件中,我导入一个WebCrawler并将Kwargs传递到其中:

    import metacrawler as mc
    mc.crawlwrapper(url=archive_url, archive_org=True, index_pages=True, depth_limit=2, fileroot='content/')
    

    调试 :yes,true参数定义为 True 在这一点上。

    {'archive_org': True}

    进入创建类实例的中间函数。下面是中间函数,它将从第一个函数到爬虫程序的所有内容进行解析:

    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 从crawwrapper(**kw)函数接收kwargs的:

    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.crawler()类方法中接收到的内容:

    depth_limit 2, confine http://www.cfu.or.ug, index_pages True, archive_org None

    注意,Achive_Org从 真的 None 是吗?

    为什么crawler没有收到我的archive_org=true参数?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Jason R. Coombs    6 年前

    因为当你写 Class(a, b) ,它通过 价值观 属于 a b 任何被定义为类(或函数)的前两个名称的名称。

    但是当你说 Class(a=a, b=b) ,你说的是“打电话” Class.__init__ 具有 设置为 a (from my scope) 并设置 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)
    

    那个 * 将表示其余参数不能按位置指定,必须用名称表示。

    老实说,我也被这个问题难住了,直到我得到了暗示。