Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 再次循环进口_Python_Python 3.x_Circular Dependency - Fatal编程技术网

Python 再次循环进口

Python 再次循环进口,python,python-3.x,circular-dependency,Python,Python 3.x,Circular Dependency,我在python3.8中有一个模块结构,如下所示: module |- __init__.py |- foo.py |- bar.py 与 #init.py from.foo导入foo from.bar导入栏 __全部uuu=['Foo','Bar',] 现在我想实现一个乘法foo*bar。所以我在写: #foo.py from.bar导入栏 Foo类: 定义初始化(自): self.value=5 定义多个(自身、其他): 如果不存在(其他,条形):提升值错误(“”) 返回self.val

我在python3.8中有一个模块结构,如下所示:

module
|- __init__.py
|- foo.py
|- bar.py

#init.py
from.foo导入foo
from.bar导入栏
__全部uuu=['Foo','Bar',]
现在我想实现一个乘法
foo*bar
。所以我在写:

#foo.py
from.bar导入栏
Foo类:
定义初始化(自):
self.value=5
定义多个(自身、其他):
如果不存在(其他,条形):提升值错误(“”)
返回self.value*other.number

#bar.py
from.foo导入foo
分类栏:
定义初始化(自):
self.number=2
定义多个(自身、其他):
如果不是isinstance(其他,Foo):提升值错误(“”)
返回其他*自我

不幸的是,这并不像预期的那样有效。在这种情况下,有没有办法进行类型检查?我知道我可以在
栏中导入Foo.\uuu mul\uuuu
——但这对我来说似乎很不整洁。

需要时导入Foo:

#bar.py
分类栏:
定义初始化(自):
self.number=2
定义多个(自身、其他):
from.foo导入foo
如果不是isinstance(其他,Foo):提升值错误(“”)
返回其他*自我
在这种情况下,酒吧是已知的,所以没有更多的问题

开始编辑

好的,稍微有点粗糙,但是您可以在类之外定义
\uuuuuuuuuuuuuuuuuuuuuuuuuuu
函数:

class Bar:
    def __init__(self, value=10):
        self.value = value

class Foo:
    def __init__(self, value=5):
        self.value = value

#    def __mul__(self, other):
#        return self.value * other.value

def mul_func(self, other):
    if isinstance(other, Bar):
        return self.value * other.value
    raise ValueError('')


Foo.__mul__ = mul_func

a = Foo(5)
b = Bar(10)
c = Foo(20)

a*b
a*c   # value error

编辑结束

我有两种解决方案,要么使用基类的变通方法,要么使用
类型以外的其他方法来知道你做得对

编辑:我想知道最初的问题是什么。因为所有这些对我来说似乎都很棘手,或者我只是没有以一种好的方式看待问题。如果我们使用
mybase.py
解决方案,为什么不为原始
foo.py
bar.py
使用单个文件呢。我想具体实施取决于你

解决方案1:基类 您的体系结构如下所示:

module
|- __init__.py
|- foo.py
|- bar.py
|- mybase.py
然后,您将拥有文件
mybase.py
,例如

classmyfoobase:
通过
MyBarBase类:
通过
然后,在您的文件
foo.py
bar.py
中,您将拥有以下文件(我将只显示一个文件,因为很明显,另一个文件是什么样子的)

from.mybase导入MyFooBase,MyBarBase
分类栏(MyBarBase):
定义初始化(自):
self.number=2
定义多个(自身、其他):
如果不是isinstance(其他,MyFooBase):raise VALUETERROR(“”)
返回other.value*self.number
解决方案2:使用其他类型。
(请参见注释)

将逻辑单元分隔为单独的包和模块可能很有用,但坚持一个文件只包含一个类几乎是教条。除非这些类很大,否则最好的解决方案是将它们固定在同一个模块中。考虑到您必须使用各种技巧来避免循环导入,那么能够为每个文件保留一个类真的值得吗

你可以做很多事情

  • 只导入模块而不导入类(
    来自模块导入foo
    ),并通过模块引用类(例如
    isinstance(obj,foo.foo)
  • 使用Python的“寻求宽恕,而不是许可”咒语。假设类的用户正确使用它们,并且操作数上存在相关属性。如果需要更多信息性错误消息,则可以在
    try:except AttributeError:
    语句中包装属性回迁,这可能会引发首选错误。您必须确保在这样的try/except块中放入最基本的逻辑。例如,
    other_value=other.value
    ,然后在try/except块之外使用
    other_value
    名称。这将停止try/except块在程序中隐藏可能的错误
  • 只得到一个类来实现
    \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
    ,这个类还可以实现
    \uuuuuuuuuuuuuuuuuuuuuuu。这允许所有实例检查只在其中一个类中完成,而不是同时在两个类中完成
  • str
    int
    是标准库使用
    计算结果的示例(例如对于
    2*“a”
    )。也就是说,当给定
    2*'a'
    时,解释器首先尝试
    int.\uuuu mul\uuuu(2,'a')
    。但是,这将返回
    NotImplemented
    。因此,解释器随后将尝试使用
    str.\uu rmul\uu('a',2)
    (返回
    'aa'
    )。但是,只有当普通运算符函数返回
    NotImplemented
    时,您才会看到他的行为。如果存在异常,则会传播此异常,而不是尝试
    \uuu rmul\uu
    。在实现运算符的
    r
    变量时,应注意
    self
    将是表达式中的正确操作数,有时这可能会改变计算结果的方式(例如
    3-1!=1-3

    第3点的例子

    X类:
    定义初始值(self,val):
    self.val=val
    Y类:
    定义初始值(self,val):
    self.val=val
    def_mul(self,x):
    如果不存在(x,x):
    返回未执行
    返回Y(self.val*x.val)
    定义多个(自身、其他):
    返回自我(其他)
    定义(自身、其他):
    返回自我(其他)
    y=y(2)*X(3)#使用mul
    断言isinstance(y,y)
    断言y.val==6
    使用rmul断言isinstance(X(3)*Y(2),Y)#
    
    您可能需要检查
    其他
    是否具有所需的属性,而不是检查
    其他
    是否为类型X?例如,
    如果不是hasattr(其他,“值”):raise
    ?这是个好主意!在我的具体案例中,属性和get的乘法有点复杂,但这将是一种解决问题的“黑客”方法。也许还有更好的主意?因为这些课