简体   繁体   中英

Python - Calling a module function which uses globals() but it only pulls globals() from the module not the current python instance

python version: 3.8.1

platform = Windows 10 pro

dev environment: visual studio code, jupyter notebook, command line

I have function that I import from a personal module to find all the current Pandas - DataFrames in memory or the globals(). However I only get the globals() from the module. (I know now that globals() only applies to the module it is called in) <--- This is my problem!

As stated above, I know this is not even remotely able to be done with the normal methodology. Here is my code from start to finish. **Note that I am calling my function from the module and this will only return "module globals()" not 'local globals()' from my current python instance's globals().

Code from "my_module" module:

# my_module.py #

import pandas as pd

module_dataframe = pd.Dataframe({'yourName'},columns = ['Name']) # creates dataframe in my module

def curDFs():
   i ='' # create variable before trying to loop through globals() prevents errors when initiating the loop
   dfList = []
   for i in globals():
       if str(type(globals()[i])) == "<class 'pandas.core.frame.DataFrame'>":
           dfList.append(i)
   return df_list   

so you can see I am creating a Dataframe in my module and creating the function curDFs() to return the name of variables in globals() that are dataframes.

Below is the code from a brand new python session:

# new_window.py #

import my_module as mm
#not importing pandas since already imported into "my_module"

new_dataframe = mm.pd.DataFrame({'name'},columns = ['YourName'])

#calling globals() here will return the "local global variable"->"new_dataframe" created above

#if i call my "curDFs()" function from the module, I return not 'new_dataframe' but the 'module_dataframe' from the module

mm.curDFs()
#returns
['module_dataframe']

I need this to return only the "new_dataframe" variable. How would I do this? I am so stuck, every other post just goes over global and local scope or how to create a config.py file of global variables. However this is going to have to be dynamic and not static as I am seeing the congig.py file to be.

I think it would be a hassle to have to build this function every single instance I spin up. I want to be able import it so I can share with others or minimize the repetitive typing caused by having to copy paste or retype in every new python instance.

Any comments or help here is much appreciated.

Sorry, it seems I did not your question carefully enough.

For your problem I found a hint at the this question.

It seems that the inspect module can do what you want:

# my_module.py #

import pandas as pd
import inspect

module_dataframe = pd.Dataframe({'yourName'},columns = ['Name']) # creates dataframe in my module

def curDFs():
    caller_frame = inspect.stack()[1]
    caller_module = inspect.getmodule(caller_frame[0])
    return [name for name, entry in caller_module.__dict__.items() if str(type(entry)) == "<class 'pandas.core.frame.DataFrame'>"]

This works on my tests, but please note that this may fail under various conditions (some caveats are at the linked post).


This is the expected behaviour. According to the Python Language Reference, Chapter 4.2.2 (Resolution of Names) (emphasis added):

If the global statement occurs within a block, all uses of the name specified in the statement refer to the binding of that name in the top-level namespace. Names are resolved in the top-level namespace by searching the global namespace, ie the namespace of the module containing the code block , and the builtins namespace, the namespace of the module builtins. The global namespace is searched first. If the name is not found there, the builtins namespace is searched. The global statement must precede all uses of the name.

The namespace of the module containing the code block in your case is the namespace of my_module.py and only of my_module.py .

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