- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
让我们考虑如下的包结构:
myApp
|-- myPackage
| |-- __init__.py
| +-- myModule.py
|-- __init__.py
+-- main.py
myModule.py 包含一个类,例如:
class MyClass( object ):
_myList = []
@classmethod
def test( cls ):
cls._myList.append( len( cls._myList ) )
return cls._myList
def __init__( self ):
return
pass
如您所见,没有什么特别的,我只是将列表定义为静态类变量。现在让我们考虑 main.py 中的代码:
from myApp.myPackage.myModule import MyClass as MyClassAbs
from myPackage.myModule import MyClass as MyClassRel
if __name__ == '__main__':
print '\n myList'
print 'MyClassAbs().test():', MyClassAbs().test() #< Prints [0].
print 'MyClassRel().test():', MyClassRel().test() #< Prints [0] but should be [0, 1].
print 'MyClassAbs.test():', MyClassAbs.test() #< Prints [0, 1] but should be [0, 1, 2].
print 'MyClassRel.test():', MyClassRel.test() #< Prints [0, 1] but should be [0, 1, 2, 3].
print '\n myList ids'
print id( MyClassAbs().test() )
print id( MyClassRel().test() )
print id( MyClassAbs.test() )
print id( MyClassRel.test() )
print ''
print 'MyClassAbs == MyClassRel:', MyClassAbs == MyClassRel #< Prints False
print 'isinstance( MyClassAbs(), MyClassRel ):', isinstance( MyClassAbs(), MyClassRel ) #< Prints False
print 'isinstance( MyClassRel(), MyClassAbs ):', isinstance( MyClassRel(), MyClassAbs ) #< Prints False
pass
问题是,在我的代码中,我从同一个模块中以不同的方式两次导入相同的类:一次作为绝对导入,一次作为相对导入。如代码的最后一部分所示,即使类相同,它们也不相等,因为它们的模块被独特地注册到 sys.modules 中:
'myApp.myPackage.myModule': <module 'myApp.myPackage.myModule' from '/full/path/myApp/myPackage/myModule.py'>
'myPackage.myModule': <module 'myPackage.myModule' from '/full/path/myApp/myPackage/myModule.py'>
因此,它们的表示不同:
'MyClassAbs': <class 'myApp.myPackage.myModule.MyClass'>
'MyClassRel': <class 'myPackage.myModule.MyClass'>
那么...有什么方法可以将此变量永久设置为静态变量吗?
编辑:
上面的代码显然只是对我的实际问题的简化。实际上,我基本上有一段代码可以递归地检查文件夹中嵌套的所有模块,并注册其中包含的类。然后可以使用通用语法实例化所有以这种方式注册的类,例如
myApp.create( 'myClass' )
这就是为什么我有时最终会有 2 个对象指向同一个类,但它们是以不同的方式导入的。一个已通过 imp.load_module() 调用自动导入,另一个将由用户通过常规导入语句直接导入。如果用户决定手动导入一个类,他应该仍然可以访问与在相同但自动注册的类中定义的静态类变量相同的静态类变量。希望它有意义?
最佳答案
没有。 (至少,并非没有非常丑陋和脆弱的技巧。)当您以这两种不同的方式导入它时,该模块实际上被导入了两次。如果您再次导入,Python 通常会重新使用已经导入的模块,但这不是基于导入的实际文件,而是基于相对于 sys.path
的路径。因此,如果您绝对地和相对地导入一次 myModule.py
,整个文件实际上会执行两次。如果您执行以下操作,您可以看到这一点:
from myApp.myPackage import myModule
import myApp.myPackage.myModule as sameModule
import myPackage.myModule
print myModule is sameModule
print myModule is myPackage.myModule
对于第一次打印,您应该看到 True
(因为前两次导入是通过相同的路径),但对于第二次打印,您应该看到 False
(因为第三次导入使用不同的路径)小路)。这也是您在 sys.modules
中看到包含两个条目的模块的原因。
因为整个模块被导入了两次,所以您实际上有两个不同的类 MyClass,而不是一个。没有合法的方式让这两个类共享它们的状态。就好像您从两个不同的模块导入了两个不同的类一样。即使它们碰巧在同一个源文件中定义,当您像这样双重导入它们时,它们也不会以任何方式链接。 ( 有一种链接它们的邪恶方法,即您可以在模块中包含代码以手动检查它是否以不同的名称导入,然后手动弄乱 sys.modules
将当前导入的模块设置为已经导入的模块。但这是个坏主意,因为很难判断导入的模块是否真的是同一个模块,而且还因为踩踏 如果原始导入或新导入因任何原因失败,sys.modules
可能会导致奇怪的错误。)
真正的问题是,为什么要两次导入模块?第二个问题是,你为什么要使用相对导入?解决方案是使用绝对导入只导入一次模块,然后就没有问题了。
关于Python:即使以不同方式导入模块,也使类变量成为静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13392038/
当我这样做时... import numpy as np ...我可以使用它但是... import pprint as pp ...不能,因为我需要这样做... from pprint import
我第一次尝试将 OpenCV 用于 Python 3。要安装,我只需在终端中输入“pip3 install opencv-python”。当我这样做时,我在 Finder(我在 Mac 上)中看到,在
如果有一个库我将使用至少两种方法,那么以下之间在性能或内存使用方面是否有任何差异? from X import method1, method2 和 import X 最佳答案 有区别,因为在 imp
我正在从 lodash 导入一些函数,我的同事告诉我,单独导入每个函数比将它们作为一个组导入更好。 当前方法: import {fn1, fn2, fn3} from 'lodash'; 首选方法:
之间有什么关系: import WSDL 中的元素 -和- import元素和在 XML Schema ...尤其是 location 之间的关系前者和 schemaLocation 的属性后者的属性
我在从 'theano.configdefaults' 导入 'local_bitwidth' 时遇到问题。并显示以下消息: ImportError
我注意到 React 可以这样导入: import * as React from 'react'; ...或者像这样: import React from 'react'; 第一个导入 react
对于当前的项目,我必须使用矩阵中提供的信息并对其进行数学计算,以及使用 ITK/VTK 函数来显示医疗信息/渲染。基本上我必须以(我猜)50/50 的方式同时使用 matlab 例程和 VTK/ITK
当我看到 pysqlite 的示例时,SQLite 库有两个用例。 from sqlite3 import dbapi2 as sqlite3 和 import sqlite3 为什么有两种方式支持s
我使用 Anaconda Python 发行版:Python 2.7 x64 和 Windows 7 SP1 x64 Ultimate。 当我import matplotlib.pyplot时,我得到
目录 【容器】镜像导出/导入 导出 导入 带标签 不带标签,后期修改 【仓库】镜像导出/导入
我正在寻找一种导入模块的方法,以便我可以从子文件夹 project/v0 和根文件夹 project 运行脚本。/p> 我在 python 3.6 中的文件结构(这就是没有初始化文件的原因) proj
我通常被告知以下是不好的做法。 from module import * 主要原因(或者有人告诉我)是,您可能会导入一些您不想要的东西,并且它可能会隐藏另一个模块中具有类似名称的函数或类。 但是,Py
我为 urllib (python3) 编写了一个小包装器。在if中导入模块是否正确且安全? if self.response_encoding == 'gzip': import gzip
我正在 pimcore 中创建一个新站点。有没有办法导出/导入 pimcore 站点的完整数据,以便我可以导出 xml/csv 格式的 pimcore 数据进行必要的更改,然后将其导入回来? 最佳答案
在 Node JS 中测试以下模块布局,看起来本地导出的定义总是在名称冲突的情况下替换外部导出的定义(参见 B.js 中的 f1)。 A.js export const f1 = 'A' B.js e
我在使用 VBA 代码时遇到了一些问题,该代码应该将 excel 数据导入我的 Access 数据库。当我运行代码时,我收到一个运行时错误“运行时错误 438 对象不支持此属性或方法”。来自我在其他论
我有一个名为 elements 的包,其中包含按钮、trifader、海报等内容。在 Button 类中,我正在执行 from elements import * 这执行正常,当我尝试 print(p
在我长期使用 python 的经验中,我遇到了一个非常奇怪的问题。 提前我想说我想知道为什么会发生这种情况 ,而不是如何更改我的代码或如何修复它,因为我也可以做到。 我正在使用 python2.7.3
我正在更新我的包。但是,我正在为依赖项/导入而苦苦挣扎。我使用了两个冲突的包 - ggplot2和 psych及其功能 alpha当然还有 alpha ggplot2 的对象不同于 alpha psy
我是一名优秀的程序员,十分优秀!