【问题标题】:How can it be a function that uses variables which are not arguments of the function?它怎么可能是一个使用不是函数参数的变量的函数?
【发布时间】:2021-11-16 19:00:01
【问题描述】:

我正在学习 Kaggle 的机器学习课程 在他们对练习的解决方案中,他们创建了一个使用 X,y 的函数,但 X,y 在函数外部定义并且它们不是全局的。

该功能仍然有效(练习在 Jupiter 笔记本上) 这是函数

def get_score(n_estimators):
    my_pipeline = Pipeline(steps=[
        ('preprocessor', SimpleImputer()),
        ('model', RandomForestRegressor(n_estimators, random_state=0))
    ])
    scores = -1 * cross_val_score(my_pipeline, X, y,
                                  cv=3,
                                  scoring='neg_mean_absolute_error')
    return scores.mean()

【问题讨论】:

  • python允许读取全局范围内定义的变量的值。
  • 作为一名程序员,您应该非常、非常非常努力不使用全局变量。

标签: python scikit-learn


【解决方案1】:

referencey 将首先搜索函数命名空间, 然后搜索模块(全局)命名空间以及内置函数, 如果没有找到最终将放弃 NameError。 y 可能被添加到函数命名空间的典型方式 将通过作为 arg 出现在签名中, 或通过在函数体内分配。 您对 cross_val_score( ... ) 的调用包括对 y 的引用。

一个分配y,默认情况下, 更新函数命名空间中现有的y 或创建一个新的本地 y(如果尚不存在)。 我们声明global y 来改变这种行为, 在模块命名空间中查找 y 并分配给 that。 有一对y 是可能的,但很少需要, 一个在本地范围内,另一个在全局范围内。 您的示例代码未分配给y, 我们尝试构建新代码 它使用命名参数或类/对象属性 而不是全局变量。

https://docs.python.org/3/reference/simple_stmts.html#the-global-statement

https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python

【讨论】:

    【解决方案2】:

    将添加有关 Jupyter 笔记本的更多信息。 Jupyter notebook 只是iPython 交互式内核的视觉包装。当您在其中一个笔记本单元格中的函数或类之外声明变量时,它会自动成为可以访问的全局变量,如this answer 中所述。如果你在 notebook 中运行 globals() 函数,你会发现情况确实如此

    Python 3.8.6 (default, Sep 30 2021, 09:13:34)
    Type 'copyright', 'credits' or 'license' for more information
    IPython 7.26.0 -- An enhanced Interactive Python. Type '?' for help.
    
    In [1]: test = 'x'
    
    In [2]: def test_func():
       ...:     print(test)
       ...:
    
    In [3]: test_func()
    x
    
    In [4]: globals()
    Out[4]:
    {'__name__': '__main__',
     '__doc__': 'Automatically created module for IPython interactive environment',
     '__package__': None,
     '__loader__': None,
     '__spec__': None,
     '__builtin__': <module 'builtins' (built-in)>,
     '__builtins__': <module 'builtins' (built-in)>,
     '_ih': ['',
      "test = 'x'",
      'def test_func():\n    print(test)\n    ',
      'test_func()',
      'globals()'],
     '_oh': {},
     '_dh': ['/Users/matthewbarlowe/code/javascript/beard'],
     'In': ['',
      "test = 'x'",
      'def test_func():\n    print(test)\n    ',
      'test_func()',
      'globals()'],
     'Out': {},
     'get_ipython': <bound method InteractiveShell.get_ipython of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x110896610>>,
     'exit': <IPython.core.autocall.ExitAutocall at 0x11089a640>,
     'quit': <IPython.core.autocall.ExitAutocall at 0x11089a640>,
     '_': '',
     '__': '',
     '___': '',
     '_i': 'test_func()',
     '_ii': 'def test_func():\n    print(test)\n    ',
     '_iii': "test = 'x'",
     '_i1': "test = 'x'",
     'test': 'x',
     '_i2': 'def test_func():\n    print(test)\n    ',
     'test_func': <function __main__.test_func()>,
     '_i3': 'test_func()',
     '_i4': 'globals()'}
    

    关于不使用全局变量的所有建议都很好,但是在进行探索性数据分析时(这是 Jupyter 笔记本的主要用例),如果您不使用全局变量,则以这种方式使用全局变量是完全可以接受的生产中的代码。一旦你需要自动化,你应该正确地确定你的变量范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-08
      • 2013-11-09
      • 2020-04-18
      • 2015-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多