I have a module file called mymodule.py, which contains the following code:
class foo:
def __init__(self):
self.foo = 1
class bar:
import foo
def __init__(self):
self.bar = foo().foo
The __init__.py file in the same directory has
from mymodule import foo
From a script in the same directory, I have the following code:
from mymodule import bar
When I try to run bar(), I get the error that No module named foo. How can I create an instance of foo in bar when they are defined within the same module file?
Classes are imported with module name first. However, you don't need to import classes in mymodule from within mymodule, just use it.
Meaning: remove the import foo line
You do not need to import an object defined in the same module:
class foo:
def __init__(self):
self.foo = 1
class bar:
def __init__(self):
self.bar = foo().foo
The import statement is intended for objects defined in other files only; you import the names defined in another python file into the current module.
Related
# utils.py
class Foo:
def __init__():
print(__file__)
# mod.py
from utils import Foo
foo = Foo()
# This prints /absoulte/utils.py
# the expected output is /absoulte/mod.py
Is it possible to make the imported class Foo initialization with current file info instead of where it defined without passing the parameter?
Here is is the directory structure:
->src/dir/classes.py
->src/run.py
# classes.py
class A():
def methA():
# class A
class B():
def MethB():
# class B
class C():
def methC():
# class C
then i need to import Class A in run.py file.
from dir.classes import A
A.methA()
i already tried with using from dir.classes import A but it gives me
ModuleNotFoundError: No module named 'dir.classes'; 'classes' is not a package error
So how can i do that?
You need to put__init__.py file on your dir folder.
This way dir will be recognized as python package.
First, you must have __init__.py in each directory for Python to recognize them as packages.
Then, you should use from dir.classes import A. A is the name of the class, you shouldn't use Class A
I declared a class with a class variable.
Module name my_moudle_1.py
For example:
class my_class:
my_dict={}#The class variable
def __init__(self):
return
In a different module - my_moudle_2.py i wrote:
from my_moudle_1 import my_class
Inside this module there is a class. In the class method i wrote:
my_class.my_dict['123']=5
In third module - my_moudle_3.py i wrote again:
from my_moudle_1 import my_class
When i am checking the my_dict variable value in the instance of my_class, i get
that the value is {}.
How can i update in a different module the class variable and use it
inside an instance in a different file?
Thanks
That shouldn't be the case. I can't reproduce this problem:
mymod.py
class my_class:
my_dict = {}
def __init__(self):
return
my_class.my_dict['foo'] = 'bar'
mymod2.py
from mymod import my_class
my_class.my_dict['greeting'] = 'Hello'
testapp.py
from mymod import my_class
import mymod2 # will modify my_dict as a side effect
my_class.my_dict['barq'] = 'foo'
print(my_class.my_dict)
$ python3 testapp.py
{'foo': 'bar', 'greeting': 'Hello', 'barq': 'foo'}
$
Are class variables essentially global variables?
Consider this example, in bar.py:
class Bar(object):
b = {}
then in foo.py:
def foo1():
import bar
bar.Bar.b["key"] = "foo1"
def foo2():
import bar
print bar.Bar.b.get("key", "foo2")
foo1()
foo2()
The "key" value is persistently "foo1."
For my purposes this seems like a global variable. But why isn't the class variable being reset or deleted between the calls to foo1 and foo2?
It's a class attribute. In your case, the dict is bound to the class Bar. Everytime you import bar, you get the same class bar.Bar (after all, it is in the bar's global namespace), and consequentially, you get the same dict bar.Bar.b.
If you want each Bar instance to have a different dict, you need to make an instance:
class Bar(object):
def __init__(self):
self.b = {}
And then:
def foo1():
import bar
bar.Bar().b["key"] = "foo1"
def foo2():
import bar
print bar.Bar().b.get("key", "foo2")
foo1()
foo2()
As far as why the module bar isn't being garbage collected, when you import something, python stores a reference to that module (see sys.modules). The next time you import that module, python picks out the proper item from sys.modules and gives you a reference to it. There are a few reasons for this.
Efficiency -- Why re-evaluate code you've already evaluated?
Sane behavior
Imagine a module with a special value:
# mod.py
CONSTANT = object()
now you want to use that in foo.py and bar.py.
# bar.py
import mod
def bar():
return mod.CONSTANT
# foo.py
import mod
import bar
if bar.bar() is mod.CONSTANT:
do_something()
If the import wasn't cached, then mod.CONSTANT could be different in foo and in bar which would be very surprising.
I have the following files in my directory:
foo/
foo.py
foolib/
__init__.py
bar.py
Within __init__.py:
__all__ = ["bar"]
Within bar.py:
class Bar:
def __init__(self):
None
def hello(self):
print("Hello World")
return
def hi():
print("Hi World")
Now if I have the following code within foo.py:
from foolib import *
bar.hi()
foobar = Bar()
foobar.hello()
"Hi World" prints, but I get a NameError for Bar(). If I explicitly import the module:
from foolib.bar import *
I get the expected output "Hello World".
Is there a way for me to import classes from the modules, without explicitly calling them? I feel like I am missing something in the __init__ file. Either that or I am flagrantly violating some Python best practice.
To import the class you must import the class, somewhere. When you do from foolib import *, because of your __init__.py this imports the module bar. It doesn't allow you to access anything inside that module.
If you want to automatically access everything in bar from the foolib package without having to import bar, you could put this in __init__.py:
from bar import *
This makes everything in bar available directly in foolib.