Because of circular imports a want to load a module this way:
try:
from ..foo import serializers as foo_serializers
except ImportError:
import sys
foo_serializers = sys.modules['app.foo.serializers']
When I use the loaded module in a class definition like this, it says app.foo.serializers has no attribute FooSerializer although it definitely has:
class SomeSerializer(ModelSerializer):
foo_field = foo_serializers.FooSerializer()
But when I use foo_serializers.FooSerializer in a class function it works. What does it mean? Are modules in sys.modules fully loaded in the time when the class definition is loaded? What could be a problem here?
Related
I have defined AUTH_USER_MODEL = 'django_restframework_2fa.User' in the settings.py file of Django application.
django_restframework_2fa is the name of the package and it has module named models where class User is defined.
Now, I want to access that User() class using AUTH_USER_MODEL constant. How can this be done?
I tried to access it like this settings.AUTH_USER_MODEL(**data) which should be equivalent to User(**data) but it doesn't work.
In python module can be imported using import_module() method of import importlib. Then to get the attributes of that module use method getattr() which takes two arguments module and attribute name.
This is how I have accomplished it -
def get_class(module_class_string):
"""
:param module_class_string: full name of the class to create an object of
:return: class
"""
module_name, class_name = module_class_string.rsplit(".", 1)
module_name = module_name + '.models'
module = importlib.import_module(module_name)
return getattr(module, class_name)
In my structure I would like to introduce circular dependency like below to avoid submiting two separate queries to backend. Can someone advise how this can be done in Python.
Below is the sample code:
parent.py
import graphene
class Parent(graphene.ObjectType):
id = graphene.ID()
name = graphene.String()
child= graphene.Field(Child)
child.py
import graphene
class Child(graphene.ObjectType):
id = graphene.ID()
name = graphene.String()
parent = graphene.Field(Parent)
test.py
from parent import Parent
print("TEST")
Error
ImportError: cannot import name 'Parent' from partially initialized module 'parent' (most likely due to a circular import)
Update
The following also doesn't work (circular import error)
import graphene
class Child(graphene.ObjectType):
import app.parent as P
id = graphene.ID()
name = graphene.String()
parent = graphene.Field(P.Parent)
...
import graphene
class Parent(graphene.ObjectType):
import app.child as C
id = graphene.ID()
name = graphene.String()
child = graphene.Field(C.Child)
...
from app.parent import Parent
print("TEST")
AttributeError: partially initialized module 'app.parent' has no attribute 'Parent' (most likely due to a circular import)
TLDR - graphene.Field('<class-loc>.<class-name>').
In your case, graphene.Field('parent.Parent') and graphene.Field('child.Child') should do the job.
Ran into the exact same issue and thought there must be some way to define the schema just using string representations instead. While going through the code I found the import_string function which is used internally that helped me understand how that can be done -
https://github.com/graphql-python/graphene/blob/a53b782bf8ec5612d5cceb582fbde68eeba859aa/graphene/utils/module_loading.py#L5
Just use "lambda". In your case:
child = graphene.Field(lambda:C.Child)
instead of:
child = graphene.Field(C.Child)
I am using Python 2.7, and have following code strucure
model
__init__.py
order.py
cart.py
That is, I define a package named model, and in this package, I define a module order, and I define a class in order.py
class MyOrder(object):
def __init__(self, name):
self.name = name
def getname(self):
return self.name
In the cart.py, the code is:
import model
x = model.order.MyOrder("Book")
print x.getname()
When I run it, it complains that AttributeError: 'module' object has no attribute 'order',
But the following is correct:
import model.order
x = model.order.MyOrder("Book")
print x.getname()
It looks that I can't import package (like import model) ?
If you want to have model automatically import order so it's available, you should do that in __init__.py. Simply put the following inside model/__init__.py:
from . import order
After that, you should be able to access model.order with just import model.
I have two classes in the same folder;
filename
Filename: twisted, class name : Root,method :def render_GET(self, request):
Filename: ladpConnector, class name:MyClass, method : getMachines(self)
I want to call getMachines from the first file, inside Root class.
I tried following options;
MyClass().getMachines()
from ldapConnector import Myclass
MyClass().getMachines()
All gives issues, undefined method/undefined variable class Myclass etc..
What is teh right way to call that method?
I'm not sure what you are asking, but you need to import that class in the file that has the Root class:
# twisted.py file
from ldapConnector import MyClass
class Root():
def __init__(self):
MyClass().getConnections()
To access files within the same module you need to do relative imports: from .ldapConnector import MyClass should work.
I am reading many doc, blog, and SE questions about this topic but I cant get it right. I have a circular import between my models.py and tms.py in a same module named maps
models.py
from maps.tms import tileMapConfig
class LayerMapOptions(models.Model):
layer = models.ForeignKey(Shapefile)
basqui_map = models.ForeignKey(BasquiMap)
position = models.IntegerField(max_length=100, blank=True, null=True)
visible = models.BooleanField(default=False)
styles = models.ManyToManyField(LayerStyle, null=True, blank=True)
def save(self, *args, **kwargs):
super(LayerMapOptions, self).save(*args, **kwargs)
self.basqui_map.date_updated = datetime.now()
self.basqui_map.save()
tileMapConfig(self.basqui_map.pk)
tms.py:
from maps.models import LayerMapOptions
result = LayerMapOptions.objects.filter(basqui_map__pk=map_id)
def tileMapConfig(map_id):
...
This result in the following error:
from maps.models import LayerMapOptions ImportError: cannot import name LayerMapOptions
What would be the way to import those submodules without conflict?
Simply put your import into the function that uses it:
def tileMapConfig(map_id):
from maps.models import LayerMapOptions
...
Or
def save(self, *args, **kwargs):
from maps.tms import tileMapConfig
...
Modules are only imported once, so each time it re-enters the function, it will not reimport the whole module, it will only fetch it from the already imported modules, so there is (almost) no performance issue.
One way is to use the full namespace.
import maps.tms
maps.tmstileMapConfig(self.basqui_map.pk)
The other issue is that you have some global code running during the import:
result = LayerMapOptions.objects.filter(basqui_map__pk=map_id)
When importing a module, the code in the module gets executed, so if you can move this line into a function or method, that will delay the execution of that line until after both modules have fully imported.
Here's a better explanation:
http://effbot.org/zone/import-confusion.htm