简体   繁体   中英

Circular Dependencies C# Projects vs Python Packages

In C# code can be organized into multiple projects. Say I have two projects ProjectA and ProjectB. I can setup ProjectB to reference ProjectA. Once I do that the classes in ProjectB can use the classes defined in ProjectA. But classes in ProjectA cannot use the classes defined in ProjectB, and ProjectA cannot also be made to reference ProjectB.

Is there any equivalent to this in python? I think a package in python is a close equivalent to a project in C#. Nothing seems to prevent circular dependencies between packages in python though. I can have modules in PackageB reference modules in PackageA, and at the same time modules in PackageA reference modules in PakcageB. This can quickly devolve into a messy web of dependencies between packages.

Are there constructs or tools in python to prevent circular dependencies the way that projects do in c#?

Python allows circular dependencies, but only very rarely is it useful.

Generally speaking though, two packages depending on each other aren't considered a circular dependency, only two modules. Ex

moduleB.py

from moduleA import B

class C:
    # definition
B.start()

moduleA.py

from moduleB import C

class B:
    @staticmethod
    def start():
# remaining definitions
d = C()

However, circular dependencies like the one mentioned here just won't work-- the default import machinery won't allow it and you'll get an error, or the imports would keep calling each other until you hit a stack overflow, unless you implement import hooks to solve it.

If packageA.moduleA imports something from packageB.moduleA, and packageB.moduleB imports from packageA.moduleA, that is allowed.

The answer is no: there's no way for a package A to detect that another package B it depends on has imported A again. This is because an import executes no code if the target has already been imported elsewhere.

# A/__init__.py
from B import foo
def go(): return foo.real()

# B/foo.py
import A
def use(): return A.go()
def real(): return 42

This a direct circularity between modules, not just packages, and it still works: if A is imported first, B.foo.A becomes a reference to the incomplete A (without go ), but that doesn't matter until use is called. That incomplete reference is created without any notification to, or check by, A .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM