On Thu, Apr 4, 2013 at 2:36 AM, Kristján Valur Jónsson < krist...@ccpgames.com> wrote: [...]
> There can be good and valid reasons to put things that depend on each > other in separate modules, for example when trying to separate modules by > functionality or simply when splitting a long file into two. > Notice that cyclic dependencies are allowed _within_ a module file. > Imagine if we decided that we could only refer to objects _previously_ > declared within a .py file, because it encouraged the good design practice > of factoring out common dependencies. > Dependency graphs of software entities can sadly not always be reduced > into a DAG, and we should, IMHO, by no means force people to keep each > cygle in the dependency graph within a single .py module. > IMO in both cases (cyclic dependencies within modules and between modules) Python's approach is consistently derived from a specific implementation strategy: names are available after they are defined. This works (at least it doesn't raise NameError :-): def f(): return g() def g(): return f() f() Because by the time f() is called, g() is defined. Note that this doesn't work: def f(): return g() f() def g(): return f() IOW there is no magic. If you think of putting objects in a dictionary, the semantics are clear. (Except for the shenanigans that the compiler carries out for determining whether something is a local variable reference or not, but that's also explainable.) This does not work: a = b b = a because the first line references b which is not yet defined. Similarly, if module A imports module B and B imports A, that works because imports are first satisfied from sys.modules, and when A is loaded, it is entered into sys.modules before its code is executed. But it may be that if A is loaded and starts importing B, B is then loaded and imports A, which finds A in the state it reached when it decided to import B. The rules here are more complicated because of what "from A import X" means (it depends on whether X is a submodule or not) but there are rules, and they are totally well-defined. The final piece of this puzzle is that, given A and B mutually importing each other, the top-level app code could start by importing A or B, and the execution order will be different then. (You can force this by putting A and B in a package whose __init__.py imports them in the desired order.) I don't really see what we could change to avoid breaking code in any particular case -- the burden is up to the library to do it right. I don't see a reason to forbid any of this either. -- --Guido van Rossum (python.org/~guido)
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com