Reputation: 23
Hi im creating a program in python and im running into what i think might be unprofessional practice. so im aware global variables are almost never the answer or good news. but consider this function here.
Method 1:
def api_call_function(player_name):
base_api = "https://secure.runescape.com/m=hiscore_oldschool/index_lite.ws?player="
api_call = requests.get(base_api+player_name)
return api_call.text
Imagine this function to be nested within quite a few functions and the function is ran somewhat regularly, so passing the base_api variable through as an argument would require passing it as an argument through many functions to reach this point.
Since pythons garbage collector works on the fly, assigning the base api string to a variable each time would waste memory and GC time. so the other options i have are not assigning it to a variable and just including it in the requests call such as the snippet below.
Method 2:
def api_call_function(player_name):
api_call = requests.get("https://secure.runescape.com/m=hiscore_oldschool/index_lite.ws?
player="+player_name)
return api_call.text
Is this bad practice? or messy?
Should i use an alternative option of having the program run within the scope of a Class object so instead of using global variable or this method to store the base_api i can instead assign the base_api string to a static class variable and since the program would be within the scope of the class it would be able to access the base api, such as this.
Method 3:
class Program:
base_api = "https://secure.runescape.com/m=hiscore_oldschool/index_lite.ws?player="
def api_call_function(player_name):
api_call = requests.get(Program.base_api+player_name)
return api_call.text
Something like that.
What is the best practice when encountering this situation?
Thankyou in advance for providing insight into the best practices.
Upvotes: 1
Views: 751
Reputation: 7736
My advice is to keep method 1 or use global constants.
First, point out a mistake:
Since pythons garbage collector works on the fly, assigning the base api string to a variable each time would waste memory and GC time.
No, it won't. Here I write a function at will as an example:
def method_1(player_name):
base_api = "https://secure.runescape.com/m=hiscore_oldschool/index_lite.ws?player="
return base_api + player_name
Check the compiled bytecode (my version is Python 3.10.8):
>>> dis(method_1)
2 0 LOAD_CONST 1 ('https://secure.runescape.com/m=hiscore_oldschool/index_lite.ws?player=')
2 STORE_FAST 1 (base_api)
3 4 LOAD_FAST 1 (base_api)
6 LOAD_FAST 0 (player_name)
8 BINARY_ADD
10 RETURN_VALUE
Note that the LOAD_CONST
instruction is used here to load strings, which means that some optimizations are possible here. In fact, it only generates the string once and stores it in the function.__code__.co_consts
:
>>> method_1.__code__.co_consts
(None, 'https://secure.runescape.com/m=hiscore_oldschool/index_lite.ws?player=')
Therefore, your concern is unnecessary. You can confidently use constants in functions.
Another possible choice is also contrary to your idea:
global variables are almost never the answer or good news
Global variables are really not a good choice, but the string object in Python is immutable. Therefore, as long as you do not use global statement in functions, the global string object is equivalent to a global constant, and using it will not harm your program. You can store them in the current namespace, or you can use another module to store global constants, depending on yourself.
For more information, please refer to Why are global variables evil?.
Upvotes: 2