简体   繁体   中英

How to Grab All Globals as a Reference in Python?

I'm working on a project that's written in Go and uses go-python to run Python code inside. The way it works is you write code.py snippits, then the Go code throws in Global variables to use the internal API.

ie code.py might look like:

some_api_call() # Linters think some_api_call is not defined, but go-python put it in the global scope

This works great, but for modularity I want my code.py to import code_2.py . Unfortunately, if I do this, code_2.py doesn't have acces to the API that the go code manually added to code.py 's global scope.

ie

code.py :

import code2.py

code2.run_func()

code2.py :

def run_func():
  some_api_call() # This fails since code2.py doesn't have the API injected

I can pass in individual API functions to code_2.py manually, but there's a lot of them. It would be easier if I could just pass everything in code.py 's Global scope, like code_2.init(Globals) . Is there an easy way to do this? I've tried circular importing, but go-python doesn't let me import the originally called script.

Thanks!

You can pass a paramter to code2.run_func() , and have run_func access api calls through its methods or classmethods.

Something like this. In code.py :

import code2.py

class Api:
    @classmethod
    def some_api_call(): ...

code2.run_func(Api)

And in code_2.py :

def run_func(api):
    api.some_api_call()

Looks like the built-in method globals() will do the trick

code.py:

import code_2

code_2.init(globals())

code_2.py:

def init(other_global_scope):
    for k in other_global_scope:
        globals()[k] = other_global_scope[k]

# code_2.py can now run some_api_call()

As suggested in the other answer, straight copying globals() can cause weird issues (since a global variable modified in one file will alter the other, as well as imports/etc), so if you're fine prefixing every API call with .api , this will be much more clean:

Top of code.py :

api = lambda: None
for k in globals():
  if k.startswith("__") or k == "api":
    continue
  setattr(api, k, globals()[k])


# api.log("Hello World!")

import code_2.py

code2.run_func(api)

Since you build the api object at the very beginning of code.py , api won't have anything except for what was passed in by the go code. You can now do

code_2.py :

def run_func(api):
  api.log("Hello World!")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM