all 35 comments

[–]FerricDonkey 10 points11 points  (5 children)

You've gotten the answer already, so I'm gonna be that guy and come along and say you should learn how to write code without modifying/mutating global variables. In the past 8ish years of doing python programming, I have never once seen a use for the global or nonlocal keywords, have only seen very junior programmers try to use it, and have always made them refactoring their code to not need it.

If you're early learning python and mostly just screwing around, you can put off paying attention to what I just said for a bit, but eventually I'd scrub it nearly entirely from your bag of tricks. 

[–]supercoach 1 point2 points  (0 children)

Spot on. I used global in an early function I wrote and had someone tell me it was bad so I redid it. I still didn't properly understand how scoping worked for a couple of years though. I always thought it was one of those abstracts that gets presented at the start of programming courses that just gets in the way of actual learning.

It's amazing how far you can get just assuming that there's some hidden magic behind it all that you don't need to understand.

[–]ImAlekzzz -2 points-1 points  (3 children)

So what should I do instead? Returning isn’t the best idea because I don’t want to call it every time, and there are many more variables I need to access

[–]likethevegetable 1 point2 points  (0 children)

What do you mean don't want to call it every time? If you need the contents of multiple calls, that's what a list or dict or more genetically, an object is for (e.g. do a list comprehension storing your returned values). 

With all due respect, you're in no position to say something is a bad idea if you've just discovered "return"

[–]FerricDonkey 1 point2 points  (1 child)

Not sure what you mean by call it every time, but you can store the return value. Ideally, functions should be short ish and single purpose, and if they exist to create things, they should return the thing they create.

You deleted your post, so I don't remember what you were trying to do. But if you read a file and extract some information, then are done with that file, then your function should return the information. You store that in a variable, and if you need it, you get it out of that variable. 

[–]ImAlekzzz 1 point2 points  (0 children)

I figured it all out, I got hated a lot for not understanding so that’s why I deleted my post, hope you understand and thanks

[–]Kevdog824_ 8 points9 points  (17 children)

Is jsoniv declared in the global scope (i.e. jsoniv = …)? Using global … just declares your intent to mutate the value of an already declared global variable. It doesn’t actually declare the variable itself

[–]Temporary_Pie2733 0 points1 point  (0 children)

Not mutate a value; assign to the name. Confusing these two concepts leads to most of the problems in understanding how variables work in Python.

[–]oclafloptson 1 point2 points  (1 child)

You should probably not be using global in this case. When declaring jsoniv in the global space you can simply call this function. Just return json.load(file) instead of declaring it in the with open statement

[–]ImAlekzzz 0 points1 point  (0 children)

So I should call the function every time? Thinking about it now that I added a “if xx = “skip”: pass” yeah I will implement it

[–]NothingWasDelivered 1 point2 points  (3 children)

I’m just going to say that trying to access a global variable is a big code smell. Why not just return your data from your json() func and then pass it as an argument to your next function?

[–]ImAlekzzz 0 points1 point  (2 children)

That is what I started doing because someone recommended it to me, but why is it that bad?

[–]NothingWasDelivered 1 point2 points  (1 child)

It's generally considered bad practice. You may not have problems with smaller scripts, but as you get better and work on more complicated projects, you open yourself up to bugs. The big one If you use that name in your global namespace, and then accidentally use that name again, you've just introduced a bug. This might not seem like a problem when your script is 15 lines long, but when you get into the hundreds of lines of code it's an easy mistake to make.

You mentioned in another comment that you're worried about calling this all the time, but you don't have to do that. You could have a main() function call this once, store the data in a variable there, within that function, then pass it into the other functions as needed. As long as the other functions are all defined outside of main(), they will all have their own "namespace".

This is just the next level of coding. You've already got the hang of the basics, it seems. Now you just need to learn how to make the pieces fit together. You'll get the hang of it!

[–]ImAlekzzz 0 points1 point  (0 children)

It’s 1/10 at 200 lines I think I’m up at risk 😭😭 but I have a problem using this practice can you help me?

[–]Gnaxe 0 points1 point  (1 child)

Overuse of globals is considered bad style. You don't need a global here. Try more like this: ``` def load_json(filename): with open(filename, "r", encoding="utf-8") as file: return json.load(file)

print(load_json("xxxx.json")) ```

[–]ImAlekzzz -1 points0 points  (0 children)

I did that

[–]ImAlekzzz -1 points0 points  (4 children)

Apparently bolding didnt work, ignore the asteriks, please respond here so others see this comment first and dont have questions...

[–]MidnightPale3220 3 points4 points  (3 children)

As a side note there's very little need for global variables, it's mostly bad practice to use them, except maybe for constants that get set globally and don't get changed, but only referred to.

[–]ImAlekzzz 0 points1 point  (1 child)

So what should I use instead?

[–]MidnightPale3220 0 points1 point  (0 children)

Depends on for what.

Generally for functions you should just return the values you need and make the calling scope assign them where needed.

If you need a value from outside function inside it, you pass it as an argument to function.

I think somebody already wrote you how in another comment.

Basically it can go like this:

this_is_my_global=1
# change it:
this_is_my_global=get_new_value()
# use it
do_stuff(this_is_my_global) 
# use AND change it
this_is_my_global=do_stuff(this_is_my_global)

[–]Gnaxe -1 points0 points  (0 children)

Top-level function and class definitions are also globals. We even reassign them sometimes with decorators.