What is the scope for imported classes in python?

Please excuse the vague title. If anyone has a suggestion, please let me know! Also please retag with more appropriate tags!

The Problem

I want to have an instance of an imported class be able to view things in the scope (globals, locals) of the importer. Since I'm not sure of the exact mechanism at work here, I can describe it much better with snippets than words.

## File 1
def f1():  print "go f1!"

class C1(object):
    def do_eval(self,x):  # maybe this should be do_evil, given what happens
        print "evaling"
        eval(x)
        eval(x,globals(),locals())

Then run this code from an iteractive session, there there will be lots of NameErrors

## interactive
class C2(object):
    def do_eval(self,x):  # maybe this should be do_evil, given what happens
        print "evaling"
        eval(x)
        eval(x,globals(),locals())

def f2():
    print "go f2!"

from file1 import C1
import file1

C1().do_eval('file1.f1()')
C1().do_eval('f1()')
C1().do_eval('f2()')

file1.C1().do_eval('file1.f1()')
file1.C1().do_eval('f1()')
file1.C1().do_eval('f2()')

C2().do_eval('f2()')
C2().do_eval('file1.f1()')
C2().do_eval('f1()')

Is there a common idiom / pattern for this sort of task? Am I barking up the wrong tree entirely?


Asked by: Sawyer254 | Posted: 01-10-2021






Answer 1

In this example, you can simply hand over functions as objects to the methods in C1:

>>> class C1(object):
>>>    def eval(self, x):
>>>        x()
>>>
>>> def f2(): print "go f2"
>>> c = C1()
>>> c.eval(f2)
go f2

In Python, you can pass functions and classes to other methods and invoke/create them there.

If you want to actually evaluate a code string, you have to specify the environment, as already mentioned by Thomas.

Your module from above, slightly changed:

## File 1
def f1():  print "go f1!"

class C1(object):
    def do_eval(self, x, e_globals = globals(), e_locals = locals()):
        eval(x, e_globals, e_locals)

Now, in the interactive interpreter:

>>> def f2():
>>>    print "go f2!"
>>> from file1 import *    # 1
>>> C1().do_eval("f2()")   # 2
NameError: name 'f2' is not defined

>>> C1().do_eval("f2()", globals(), locals()) #3
go f2!
>>> C1().do_eval("f1()", globals(), locals()) #4
go f1!

Some annotations

  1. Here, we insert all objects from file1 into this module's namespace
  2. f2 is not in the namespace of file1, therefore we get a NameError
  3. Now we pass the environment explictly, and the code can be evaluated
  4. f1 is in the namespace of this module, because we imported it

Edit: Added code sample on how to explicitly pass environment for eval.

Answered by: Kate216 | Posted: 02-11-2021



Answer 2

Functions are always executed in the scope they are defined in, as are methods and class bodies. They are never executed in another scope. Because importing is just another assignment statement, and everything in Python is a reference, the functions, classes and modules don't even know where they are imported to.

You can do two things: explicitly pass the 'environment' you want them to use, or use stack hackery to access their caller's namespace. The former is vastly preferred over the latter, as it's not as implementation-dependent and fragile as the latter.

You may wish to look at the string.Template class, which tries to do something similar.

Answered by: Ryan988 | Posted: 02-11-2021



Similar questions

python - How do you get all classes defined in a module but not imported?

I've already seen the following question but it doesn't quite get me where I want: How can I get a list of all classes within current module in Python? In particular, I do not want classes that are imported, e.g. if I had the following module: from my.namespace import MyBaseClass from somew...


python - How to view imported classes from py4j gateway

Consider the following py4j gateway init code: from py4j.java_gateway import java_import, JavaGateway, GatewayClient gateway = JavaGateway(GatewayClient(port=gateway_port), auto_convert=False) java_import(gateway.jvm,'org.apache.hadoop.hbase.client.*') java_import(gateway.jvm,'org.apache.hadoop.hbase.filter.*') What code could be invoked on the gateway to view the imports it cont...


Python, could I import * without Imported classes

Let's pretend that I have this file called file1.py: from app1 import ClassX class Class1: pass class Class2: pass If in another file called file2.py I want to import Class1 and Class2 without explicit import this classes I usually need to use from file1 import * My problem is, when I do it I'm ...


How to get the same scope for imported classes in a Python script?

This question already has answers here:


python - How can I expose, together with my classes, the types imported from the glm Haxe lib?

I am writing a class that I will translate to both Python and C#. My code uses the nice "glm" library. Glm provides useful datatypes, e.g: Vec3. Can I make Vec3 visible to the Python and C# users of my class? In other words, can I expose public methods using Vec3 datatypes? Here is a sample Haxe code with a class whose public function uses the Vec3 type:


python - How to handle to imported classes in Sphinx

I have a package with the following abbreviated directory structure: package/ __init__.py a.py b.py docs/ source/ a.rst b.rst __init__.py contains: from .a import A from .b import B a.py contains from .b import B I am using "show-inheritance" in the rst A...


for loop - How do I make a list of imported classes in Python?

from module import a, b, c foo(a) foo(b) foo(c) Is there a way to avoid having to call foo(x)for each imported object? Some context: a, b, c are webpage classes and foo is a route() function that creates a route for each webpage. Update: There will be a growing list of imported classes in the main module as the application grows. I mentioned a, b, and c simply as an examp...


Python get line number of classes from imported module

I have been using importlib to get the module from an imported python file and would like to get the line number where each class is defined in the python file. For example I have something like this: testSpec = importlib.util.spec_from_file_location("", old_file) testModule = importlib.util.module_from_spec(testSpec) testSpec.loader.exec_module(testModule) Where old_file is a pyth...


Can you define aliases for imported modules in Python?

In Python, is it possible to define an alias for an imported module? For instance: import a_ridiculously_long_module_name ...so that is has an alias of 'short_name'.


python - Getting file path of imported module

This question already has answers here:


import - How to reload a Python module that was imported in another file?

I am trying to learn how Python reloads modules, but have hit a roadblock. Let's say I have: dir1\file1.py: from dir2.file2 import ClassOne myObject = ClassOne() dir1\dir2\file2.py: class ClassOne(): def reload_module(): reload(file2) The reload call fails to find module "file2". My question is, how do I ...


matlab - How to access fields in a struct imported from a .mat file using loadmat in Python?

Following this question which asks (and answers) how to read .mat files that were created in Matlab using Scipy, I want to know how to access the fields in the imported structs. I have a file in Matlab from which I can import a struct: >> load bla % imports a struct called G >> G G = Inp: [40x40x...


package - Find which python modules are being imported

What's an easy way of finding all the python modules from a particular package that are being used in an application?


python - How to prevent a module from being imported twice?

When writing python modules, is there a way to prevent it being imported twice by the client codes? Just like the c/c++ header files do: #ifndef XXX #define XXX ... #endif Thanks very much!


unit testing - Mocking imported modules in Python

I'm trying to implement unit tests for function that uses imported external objects. For example helpers.py is: import os import pylons def some_func(arg): ... var1 = os.path.exist(...) var2 = os.path.getmtime(...) var3 = pylons.request.environ['HTTP_HOST'] ... So when I'm creating unit test for it I do some mocking (minimock in my case) and replaci...


python - Using imported modules in more than one file

This question is a bit dumb but I have to know it. Is there any way to use imported modules inside other imported modules? I mean, if I do this: -main file- import os import othermodule othermodule.a() -othermodule- def a(): return os.path.join('/', 'example') # Without reimporting the os module The os module is not recognized by the...


python - Using Pygame Module from imported script

Greetings! I'm creating a simple snake game. I want to expand my classes in different modules e.i. have menu class in a separate script from my main game loop. In other words, I want my imported script to take the pygame init which was called earlier in main script. Here is a quick example using pseudo code of my problem: one.py def version(): print pygame.version In ma...


What could cause a python module to be imported twice?

As far as I understand, a python module is never imported twice, i.e. the code in the module only gets executed the first time it is imported. Subsequent import statements just add the module to the scope of the import. I have a module called "TiledConvC3D.py" that seems to be imported multiple times though. I use pdb to print the stack at the top of the code for this module. Here is the end of the stack tr...






Still can't find your answer? Check out these communities...



PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python



top