开发者

strange django import behaviour

Could someone please explain this behaviour:

django project called foo

file bar/models.py:

class MyModelError(TypeError):
    pass

class MyModel(models.Model):
    ...

./manage.py shell

>>> from foo.bar.models import MyModel as m1
>>> from bar.models import MyModel as m2
>>> from foo.bar.models import MyModelError as e1
>>> from bar.models import MyModelError as e2
>>> m1 is m2
True
>>> e1 is e2
False

False?!

>>> m1
<class 'foo.bar.models.MyModel'>
>>> m2
<class 'foo.bar.models.MyModel'>
>>> e1
<class 'foo.bar.models.MyModelError'>
>>> e1
<class 'bar.models.MyModelError'>

any idea of what i'm doing wrong here? My workaround (other than making sure i import the 'correct way') is to make the error class a member of the model itself (like django model.DoesNotExists) but i'd like t开发者_如何学Goo know what is going on


Django uses metaclasses for defining models. There's a check in there to avoid defining a model twice, so when a class is created if it's already been defined then you get the version that was defined before. See django.db.models.base.ModelBase:

from django.db.models.loading import get_model

# Bail out early if we have already created this class.
m = get_model(new_class._meta.app_label, name, False)
if m is not None:
    return m

Whereas the Error classes are regular Python classes and there is no such caching you get different versions, as the modules they belong to are different. I think this occurs, because when running Django runserver you end with two ways of loading the same module from the path:

  • The current directory
  • The directory above the current directory

This is so that you can import fully-qualified packages (including project name) and have things work.

I tend to never import using the project name to avoid this problem.


In most programming languages, error hangling have a stair-like mechanism. So if an error occurs, exception mechanism starts to search for an exception for handling the error. If exception could not be handled in that class, it keeps search upper levels through classes which that class is derived from.... It keeps this process tgrough the uppermost level of the inheritance...

So you are defining an ModelError class derived from TypeError , And importing that class from a different path may cause python interpereter to recognize these two as different classes.

Python Documentation

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜