Skip to content Skip to sidebar Skip to footer

How Can It Be A Function That Uses Variables Which Are Not Arguments Of The Function?

I'm taking Kaggle's ML course and in their solution to an exercise they create a function that use X,y but X,y defined outside the function and they aren't global. and still the fu

Solution 1:

A reference to y will 1st search the function namespace, then search the module (global) namespace along with builtins, and if not found will finally give up with NameError. Typical ways that y might be added to the function namespace would be by appearing in the signature as an arg, or by being assigned within the function body. Your invocation of cross_val_score( ... ) includes a ref to y.

An assignment to y will, by default, update existing y in the function namespace or create a new local y if not already present. We declare global y to change that behavior, to look for y in the module namespace and assign to that instead. It is possible but seldom desirable to have a pair of y's, one at local scope and another at global scope. Your example code does not assign to y, and we try to structure new code so it uses named arguments or class / object attributes rather than globals.

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

Solution 2:

Will add just a bit more information about Jupyter notebooks. Jupyter notebooks are just a visual wrapper around the iPython interactive kernel. When you declare a variable outside a function or class in one of the notebook cells it automatically becomes a global variable that can be accessed as described in this answer. If you run the globals() function in the notebook you'll see that this is the case as so

Python 3.8.6 (default, Sep 302021, 09:13:34)
Type'copyright', 'credits'or'license'for more information
IPython 7.26.0 -- An enhanced Interactive Python. Type'?'forhelp.

In [1]: test = 'x'

In [2]: deftest_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()'}

All the advice about not using globals is good, however when doing exploratory data analysis (as is the main use case of Jupyter notebooks) it is perfectly acceptable to use globals in this fashion if you aren't using the code in production. Once you need to automate you should properly scope your variables.

Post a Comment for "How Can It Be A Function That Uses Variables Which Are Not Arguments Of The Function?"