1

Python rookie question, in the following code,how does batch_size passing into sub function eval_on_data ? Is it global variable?

epochs = 10 
batch_size = 128

def eval_on_data(X, y, sess):
    total_acc = 0
    total_loss = 0
    for offset in range(0, X.shape[0], batch_size):
        end = offset + batch_size
        X_batch = X[offset:end]
        y_batch = y[offset:end]

       loss, acc = sess.run([loss_op, accuracy_op], feed_dict={features: X_batch, labels: y_batch})
        total_loss += (loss * X_batch.shape[0])
        total_acc += (acc * X_batch.shape[0])

   return total_loss/X.shape[0], total_acc/X.shape[0]

   ...

   val_loss, val_acc = eval_on_data(X_val, y_val, sess)
Hong
  • 526
  • 6
  • 21

3 Answers3

3

Variables that are only referenced inside a function are implicitly global. If a variable is assigned a value anywhere within the function’s body, it’s assumed to be a local unless explicitly declared as global.

From: https://docs.python.org/3/faq/programming.html

Mark
  • 90,562
  • 7
  • 108
  • 148
  • I feel this quote is misleading as the context here seems to be specific to toplevel functions. The more pertinent quote from the documentation is this one: "When a name is used in a code block, it is resolved using the _nearest_ enclosing scope. The set of all such scopes visible to a code block is called the block's *environment*. If a name is bound in a block, it is a local variable of that block. If a name is bound at the module level, it is a global variable. If a variable is used in a code block but not defined there, it is a *free variable*." – Tasos Papastylianou Jul 27 '17 at 21:47
1

Look at the following code snippet as an explanation:

a, b, c = 1, 2, 3

def fun1():
  a = 4
  def fun2():
    b = 5
    print a,b,c

  fun2()

>>> fun1()
4 5 3
>>> print a,b,c
1 2 3

When you define a function, it 'inherits' variables from the calling scope.
Obviously, once you redefine that variable locally within a function, then the local definition applies for the remainder1 of the function.

This is why fun1 inherits b and c, defined at "top level" (i.e. fun1's enclosing scope), which it then passes on further to the 'nested' function fun2.

fun2 (whose enclosing scope is fun1) then inherits a as defined within fun1, as well as b and c, since this was inherited by fun1.

Specifically, note that a inside fun2 is 4, not the global 1 (as another answer here seemed to suggest).

When you only have one function defined at top level, you could conceptually perceive that as being 'nested' at the top level, and therefore inherits the variables defined at top level (i.e. effectively global scope, even if not explicitly defined as such via the global keyword).

Have a look at help("NAMESPACES") for more details


1.To be clear, I don't mean that you can use the inherited value for a while and suddenly define a local version half-way through; if you do this python will complain that you tried to "use a local variable before assignment". I just mean that you either use the inherited version, or explicitly redefine it, which effectively makes it a local variable of the same name for use in that function.

Tasos Papastylianou
  • 21,371
  • 2
  • 28
  • 57
-2

Edit: Pythons global variable access is not as strictly enforced as in other languages. See this Answer. Similarly, python's encapsulation is unlike other languages, too. See this or this Answer

kaze
  • 35
  • 2
  • 1
    Except Python _does_ have class encapsulation, just not specified class access control. Which is a different matter entirely from global variable access. – miradulo Jul 27 '17 at 20:40