【问题标题】:Object instance type checking from another file从另一个文件检查对象实例类型
【发布时间】:2021-10-27 19:59:54
【问题描述】:

我已将我的 python 代码模块化为三个文件。 File1.py 有一个类定义,其方法和属性在类内部定义。 File2.py 充当程序输入之间的层,然后调用方法并对这些输入进行操作,基本上充当接口。虽然 File3.py 我将其用于输入的完整性检查。我正在使用 File3.py 中定义的一些完整性检查装饰器来装饰类的相关方法。一个这样的装饰器有 python 的isinstance(input_received, class_name)。现在,由于检查发生在 File3 中,类定义在 File1 中,装饰器仅将类方法作为输入,其中 input(class) 方法具有(self, input_received) ,我的isinstance(input_received, class_name) 语句抛出了"'class_name' is unknown" 的错误,这意味着class_name 定义不在File3 的范围内。 我在 File1 中导入了 File3,在 File2 中导入了 File1。 此外,循环导入不是一种选择。这将是一件愚蠢的事情。我的意思是,除了所有现有的导入之外,还要在 File1 中导入 File3。

请帮忙!

文件 1 (arith.py)

import decors # importing the decorator for input sanity check

class Coords(object):
    def __init__(self, x, y):
        self.abscissa = x
        self.ordinate = y

    def __add__(self, other):
        """ Normal left operand addition """
        return Coords(self.abscissa + other.abscissa, self.ordinate + other.ordinate)

    def __neg__(self):
        """ Negation """
        return Coords(-self.abscissa, -self.ordinate)

    @decors.neg_san_check # decorating __sub__ method
    def __sub__(self, other):
        """ Normal left operand subtraction """
        return self + other.__neg__()

文件 3 (decors.py)

from functools import wraps

def neg_san_check(func):
    @wraps(func)
    def wrapper(obj_ref, other_obj):
          if isinstance(other_obj, (Coords, int, float)):
                func(obj_ref, other_obj)
    return wrapper

文件 2 (base.py)

from arith import Coords

c1 = Coords(3,6)
c2 = Coords(7,8)

diff = c1-c2
print(diff.abscissa)
print(diff.ordinate)

这是一个错误:

Traceback (most recent call last):
  File "base.py", line 6, in <module>
    diff = c1-c2
  File "/home/somepath/codedir/decors.py", line 6, in wrapper
    if isinstance(other_obj, (Coords, int, float)):
NameError: name 'Coords' is not defined

注意:所有3个文件都位于codedir目录

【问题讨论】:

  • @juanpa.arrivillaga 我已根据您的要求编辑了提供 MRE 的帖子。我试图重现类似的场景,但并不完全相同(因为原始代码库太大)。希望你会发现它有用。

标签: python python-3.x python-decorators python-packaging modular-design


【解决方案1】:

在浏览了许多网站之后,我想出了 File3 (decors.py)

的解决方案
from functools import wraps

def neg_san_check(func):
    @wraps(func)
    def wrapper(obj_ref, other_obj):
          if isinstance(other_obj, (obj_ref.__class__, int, float)):
                func(obj_ref, other_obj)

我还想再添加一个场景: 假设如果我们确保传递的实例(other_obj)是某个其他类的类型(不同于 'obj_ref.class',那么我们可以传递该 OTHER CLASS 的类变量(其唯一目的是用于对自己的类进行类型检查)到当前类中装饰的函数。

【讨论】:

    【解决方案2】:

    decors.py 不导入Coords,因此if isinstance(other_obj, (Coords, int, float)) 行抛出异常。
    将装饰器移至arith.py 应该可以解决问题。

    【讨论】:

    • 但是我已经在 arith.py 中导入了 decors.py。不是循环导入,两个文件互相导入吗?或者,我做错了吗?
    • @saint_sharan 为什么在同一个 py 模块中没有装饰器和 Coords?毕竟装饰器是献给Coords的——不是吗?
    • 因为,我已经模块化了我的代码库。每个文件都有不同的用途
    • 但是由于装饰器是为Coords“量身定制”的,因此将它放在其他模块中是没有意义的。这样做没有任何附加价值。
    • 正如我提到的,我没有提到我的完整代码。它只是对我的真实代码的一种刺激,它正在为许多其他类进行类型检查。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多