Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
use of global
#11
with 4000+ lines of code base better put your efforts to refactor without using globals.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#12
(Sep-30-2019, 10:33 AM)buran Wrote: Actually it's a perfect example as to why using global variables should be avoided... There are problems on so many levels.
[ ... ]
You are using star import - from testglobalsextimport import *. Like globals this is bad practice and strongly discouraged.

Wpo, I think Buran has been wisely advising for a very long time in here (more than 4000 posts!!!) and is a moderator here. Computer languages, like almost everything else, evolve and change with time. If you use books like myself, you can find that even in books printed in 2019, they dedicate just one paragraph to the f-string formatting, while in internet (including this site) the use of %-formatting is deprecated in favour of the advised f-string formatting. Dedicated programmers find bugs and advise in order to code better and with more efficiency.

So, I would follow Buran, when advising not to use global variables.

(Sep-30-2019, 11:56 AM)wpo Wrote: I've been experimenting further and I think that I got most of it working! See below. "most of it" because I conclude that passing values (in global variables) between functions that reside in different modules is (almost???) impossible. Between modules, values are always to be passed as arguments in function calls and in returns.

It seems that you concur with him.

All the best,

(Sep-30-2019, 12:47 PM)buran Wrote: with 4000+ lines of code base better put your efforts to refactor without using globals.

Oops! Once again, seconds away ... Sorry!

All the best,
newbieAuggie2019

"That's been one of my mantras - focus and simplicity. Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple. But it's worth it in the end because once you get there, you can move mountains."
Steve Jobs
Reply
#13
I would love to avoid using statements that could easily produce bugs and that require scripts and modules that consist of many long lines of code. But one needs to write "programs" that do what the business processes requires. If a business process is complex, one cannot "translate" that in a small set of short scripts.

In my case, I've considered (and tried) other ways (like arguments and classes) to avoid using globals. But these other ways forced me into very long and complex lines of code that quickly result in an almost unreadable "program". Some statements on the internet, stating "globals are OK if used correctly", combined what the fact that "globals" in theory provide the functionality that I need without to much "overloading" statements with lots of names of variables and arguments, made me look into globals again.

To avoid accidentally mixing using global variables with local variables, I make sure that all names of global variables begin with the same letters (Glbl....). That makes it easy to spot them in a script. And it reminds that the "global" statement are to be added where required.

B.t.w.: Of course I beleave you that certain constructions are better not used. But in these cases, I would like to be pointed to an alternative solution to my problem ("how can I get the required result without using the not-recommended way"), preferably with examples, rather than "don't do this", like many other forums do.
Reply
#14
But why do it that way? What's the advantage to using globals instead of parameters and return values? Take the last bit of code you posted. In it you have d=finit(x). This changes the global variables a, b, and c. But there is no way to know that from looking at that line of code. That makes your code harder to follow, and therefore harder to maintain, and also easier for bugs to creep in. And why assign to d? finit has no return value, so d is always going to be None.

If finit was instead:

def finit():
    return 'ai', 'bi', 'ci'
and you called it with a, b, c = finit(), it would be clear that a, b, and c are changed by the finit function. Then f1 could be defined as:

def f1(a, b, c, x):
    print('f1: ', a, b, c, x)
and when you call it, it becomes clear that f1 is making use of those variables.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#15
(Sep-30-2019, 01:27 PM)wpo Wrote: In my case, I've considered (and tried) other ways (like arguments and classes) to avoid using globals.

I think another reason for not using global variables is that global and local variables are taken as different variables altogether. Consider this little program:

# locals_01.py
#

def print1():
    str1 = 'This would have been a GLOBAL variable.'
    print(str1) # prints 'This would have been a GLOBAL variable.'


def print2():
    str1 = 'This would have been ALSO a GLOBAL variable.'
    print(str1) # prints 'This would have been ALSO a GLOBAL variable.'
    print1()
    print(str1) # prints 'This would have been ALSO a GLOBAL variable.'


str1 = 'This would have been a LOCAL variable.'
print2()
print(str1) # prints 'This would have been a LOCAL variable.'
that uses a 'str1', similar to the way you might have used 'a' (also 'b' and 'c', but just for the demonstration, I think 'str1' like 'a' is enough). This produces this output:

Output:
This would have been ALSO a GLOBAL variable. This would have been a GLOBAL variable. This would have been ALSO a GLOBAL variable. This would have been a LOCAL variable.
where you can see that even having the same name, the variable 'str1' is indeed three different variables in this program, but confusingly they are all named 'str1' (similar to your "a's", "b's" or "c's"). The variables are as follows:
1) A variable named 'str1' that exists in a GLOBAL scope when print1() is called.
2) A variable named 'str1' that exists in a GLOBAL scope when print2() is called.
3) A variable named 'str1' that exists in the LOCAL scope.

so you can also imagine the problems that this method produces in a big program like yours.

You asked also for another way. I think you could follow the ideas from Ichabod801:

(Sep-30-2019, 01:43 PM)ichabod801 Wrote: But why do it that way? What's the advantage to using globals instead of parameters and return values? Take the last bit of code you posted. In it you have d=finit(x). This changes the global variables a, b, and c. But there is no way to know that from looking at that line of code. That makes your code harder to follow, and therefore harder to maintain, and also easier for bugs to creep in. And why assign to d? finit has no return value, so d is always going to be None.

If finit was instead:

def finit():
    return 'ai', 'bi', 'ci'
and you called it with a, b, c = finit(), it would be clear that a, b, and c are changed by the finit function. Then f1 could be defined as:

def f1(a, b, c, x):
    print('f1: ', a, b, c, x)
and when you call it, it becomes clear that f1 is making use of those variables.
newbieAuggie2019

"That's been one of my mantras - focus and simplicity. Simple can be harder than complex: You have to work hard to get your thinking clean to make it simple. But it's worth it in the end because once you get there, you can move mountains."
Steve Jobs
Reply
#16
Ichabod: I see your point. In my case I need functionality that I can call upon in several parts of my main script, while at the same time I do not want to expose the internal technical details to the main script. In my latest example, the "global variables" are only visible in the module that contains the functions, not to the main script.
If I would use function-calls and arguments instead, then the arguments that are potentially modified in the functions must be managed in the main script (because if managed in the called fucntions, the modifications disappear at the return). If I would use function calls with arguments, then the arguments must be passed from the main program to the functions and back, so the "global" variables must be managed in the main script, where they make it more difficult to "read and understand" the script.
Reply
#17
(Sep-30-2019, 03:06 PM)wpo Wrote: Ichabod: I see your point. In my case I need functionality that I can call upon in several parts of my main script, while at the same time I do not want to expose the internal technical details to the main script. In my latest example, the "global variables" are only visible in the module that contains the functions, not to the main script.
Don't you see the contradiction? if you encapsulate your code and pass argument to functions and get result all the internals are irrelevant to the caller. It's like a black-box - you pass some arguments as input and get the result you know is correct (because you ere able to test it easily). Internals are irrelevant to the caller and not exposed. Note that modifications does not "disapper" as you claim/think. Your function will return whatever you want "to preserve" and then you assign it to a variable in the caller module.
If you can't explain it to a six year old, you don't understand it yourself, Albert Einstein
How to Ask Questions The Smart Way: link and another link
Create MCV example
Debug small programs

Reply
#18
(Sep-30-2019, 03:06 PM)wpo Wrote: the "global" variables must be managed in the main script, where they make it more difficult to "read and understand" the script.

If you really think that intentionally hiding what the code is doing will make it easier to understand, I'm glad I will never have to deal with any of your code.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#19
To add onto the conversation, the following two implementations effectively have no functional difference in the program; the latter does have an unstated benefit though.

def f1():
    global a, b
    a += 4
    b += 5

def f2(a, b):
    return a + 4, b + 5

a = 5
b = 4
f1()
print(a, b)

a = 5
b = 4
a, b = f2(a, b)
print(a, b)
What happens if you need to write a new program using the same logic as f1() but you want to preserve the original values of the variables? Well, you have to rewrite f1() altogether. Then, if the logic changes, you now have two versions of it to update.

With f2(), you can reset the original variables or not; that's entirely up to the caller. f2() is infinitely reusable and can be employed even without global variables existing. Plus, f2() is 100% testable because it's stateless. With the same input, it will always have the same output; whereas f1() is entirely dependent on unseen and possibly unknown values - this is what makes global variables difficult to follow.
Reply
#20
The fact that you came here asking for help is evidence that globals don't scale. In theory there are times they're ok, but do you know how many times I've needed them? Zero. I've been coding since 2005 and working professionally for the last six years and I've never used one, in any language, and if I submitted code for review using one, it'd never get approved. You know what happens when I interview people and they use a global? 100% of the time, there's a bug. I'm not exaggerating when I say 100%. I've done hundreds of interviews and using a global was only ever bad.

You may have struggled with classes and other methods of removing globals, but they are 100% worth it. With 4k LOC full of globals, I'm certain you have bugs that you don't know about. Testing code with globals is difficult, so you may not know they're there, but I'm certain unless every author of that code is cleverer than anyone I've ever met. I'm not going to continue trying to convince you, I'm just telling you: millions of programmers before you have regretted using globals, and you have an opportunity right now to learn from all those mistakes, instead of making the exact same ones on your own and coming to the same conclusion anyway.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Global variable does not seem to be global. Columbo 6 3,711 Jul-15-2019, 11:00 PM
Last Post: Columbo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020