【问题标题】:Modules that rely on each other相互依赖的模块
【发布时间】:2013-04-06 18:34:37
【问题描述】:

我有一个 bind_form 自定义装饰器,它将指定的 django 表单分配给函数。此装饰器将允许对函数参数“自动”执行验证 - 例如,检查 age 是否在所需范围内,或检查用户是否存在。这样做是出于 DRY 的原因。

装饰器中引用的每个表单都位于forms 模块中。

users.check_user_exists 是这种表单验证的一个示例 - 因此我必须在 form 模块中导入 users 模块。

所以,现在您看到我有 forms 模块,它导入了 users 模块,因此可以引用 users.user_exists,但 users 导入了 forms 模块,因此可以在表单中使用表单装饰师:

forms.py:

import users

def bind_form(func):
    # binds form to function
    ...

class Create_User(Forms.Form):
    # validated create_user function
    ...
    def clean(self): #using for validation
        if users.user_exists(user):
           ...

users.py:

import forms

@forms.bind_form(form=forms.Create_User)
def create_user(**kwargs):
    ...

所以一旦users 被导入,users 就会尝试引用bind_form,但这还没有被forms“看到”。

这是我的设计缺陷,还是我遗漏了一些简单的东西?如果存在设计缺陷 - 欢迎提出改进建议。

** 约束:**

  • forms 模块中有多种形式。
  • users 模块中的许多函数都附有验证表单。
  • 验证表单使用来自users 和其他模块的许多函数。

换一种方式解释:

一个。 formsforms 模块的第 4 行导入 users

b. users.create_user引用forms.Create_User

c。 forms 不知道 Create_User 但因为它是在 forms 模块的第 5 行声明的

【问题讨论】:

  • 这取决于您是否曾在 forms.py 的全局范围内引用符号 users。由于您的示例似乎根本没有引用它,因此很难说。 ;)
  • 我受到了这个问题的影响 - 不幸的是,这不是假设。
  • 我从来没有说过这是假设性的,我的意思是您的代码示例没有提供足够的信息来给出具体的答案。
  • 我是否应该假设forms.py 中的if user_exists(user) 行实际上应该是if users.check_user_exists(user)

标签: python django django-forms decorator python-decorators


【解决方案1】:

循环依赖的技巧是在全局范围内分离语句,这样所有不引用从其他模块导入的任何符号的语句都在导入之前发生。比如……

forms.py:

# This statement doesn't reference 'users' at compile time
def bind_form(func):
    ...

# This statement doesn't reference 'users' at compile time
class Create_User(Forms.Form):

    # This statement declares a new scope
    def clean(self):

        # This statement references 'users' at runtime, but not at compile time
        if users.user_exists(user):
            ...

# Now import
import users

users.py:

# Import
import forms

# This statement references 'forms' at compile time
@forms.bind_form(form=forms.Create_User)
def create_user(**kwargs):
    ...

Create_User.clean() 方法中users 符号的使用不在全局范围内,因此在实际调用函数之前实际上不需要定义符号。

【讨论】:

  • 在您的回答中,forms.Create_User 尚未在 users 被引入时声明,因此users.create_user 无法引用它。我们可以扩展您的答案并说“在forms 模块的末尾导入users”,但这不起作用,因为forms 引用了users 中的函数
  • 忘了它只在全球范围内很重要。更新了答案。
  • 正如您上面的评论中所解释的那样“我们可以扩展您的答案并说“在表单模块的末尾导入用户”,但这不适用于用户中的表单引用功能'跨度>
  • 等等。 if users.user_exists(user) 是直接在class Create_User(Forms.Form) 里面,还是里面应该有方法?
  • 它在方法中使用。我稍微减少了代码。这有什么改变吗?如果是这样,我可以将它放在问题中的方法中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-25
  • 2021-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-17
相关资源
最近更新 更多