How to construct bash procedure using python?

Does anyone know how I could replicate, using Python, a mechanism (procedure, function or other) where I don't need to pass variable/object references but which will manipulate those same variables/objects, and maybe assign values to those variables ... and have those accessible by the main program itself ?

For example, I want to be able to do the equivalent of this bash script as Python:

#!/bin/bash

a=0

funcActions()
{
	b=5	# NOTE: parameter definition originating inside procedure
	for index in 1 2 3 4 5 6
	do
		val=$(expr ${index} \* ${index} )

		# NOTE: array definition originating inside procedure
		file_array[${index}]="${val}"
	done
}

funcActions

# NOTE: variable 'b' accessible and used by main program
c=$(expr ${a} + ${b} )
echo "c = ${c}"

# NOTE: array 'file_array' accessible and used by main program
printf "\"%s\"\n" "${file_array[@]}"

So ... I do not want to define either "b" or "file_array" in the main program, but still want to access those items and the values assigned in the main program.

Is such a thing possible with Python, because everything I've looked at seems to indicate that it is not possible for variables or values created withing Python "procedures" or functions" or other mechanism, without first defining them as a "global" variable and the need to specifically pass the parameters and values from the main into the function before returning those back to the main program.

Is that possible?


WHY do I want to know how to do this ?
I am tinkering with trying to create an updated, single-player, 2D game (a.k.a. boardgame) of Battleship, having some features which would make it much more "realistic" in terms of complexity, while still maintaining a simplicity that shows that it is solidly rooted in the original 1967 2D game.

You can use the global keyword inside a function:

def foo():
    global b
    # declaration and assignment must be separate
    b = 0

foo()
print(b)
3 Likes

I am shocked. It could not ever dawned on me that a global module variable could be declared and created from within a function!

3 Likes

That is impossible by definition. You see, a global variable has to belong to the global (i.e. module) scope. Local variables which belong to the local (i.e. function) scope are inaccessible from other scopes. Period.

@Stephen_Wade brilliantly showed us that Python implementation allowed to define and create a global variable from within a function's scope. Nevertheless, it became the global, module level variable.

In general, I would strongly warn against such a move. It is unsafe and results in bloated code which is hard to understand and debug. IMHO there is no reasont not to init a global variable at the module level.

import ...
# globals
a = None
...
# functions

And finally, you can write a function which would return data in question to init global variable myvar = myfunction()

4 Likes

I think the reason this isnt a common pattern is because you always want it to be clear which variable is being used.

For example:

def foo():
    global b
    b = 1

def bar():
    b = 2

foo()
bar()
print(b)
1 Like

@Stephen_Wade , @ugnvs ,

While I have correctly tagged Stephen's response as the solution to my original problem, upon reflection, and experience with an earlier program, I believe I should stick to "proper" practices for modularization and define my variables in the main program and perform proper parameter-typing at function definition and object reference passing.

Thank you both for your feedback.

My earlier, and only, experience with Python can be seen here

4 Likes

@ericmarceau I'd like to clarify myself. I only suggested that you declare your global variables at the module level, not from within a function. The following pattern is perfectly legal, well-understandable and allows to avoid passing glob1 as parameter.

glob1 = 1

def f1():
  global glob1
  # use or modify glob1 variable
  # without parameter passing

Usually one relies on function's return <value> to get some data from it. Using parameters to get some data back can be not so obvious and confusing. Just have a look at