如何替换导入库中的导入?
How to replace imports in imported library?
假设,我们有 3 个文件:
library1.py:
SomeVariable = '1'
library2.py:
import library1
print(library1.SomeVariable)
library3.py:
SomeVariable = '2'
我的目标是在 library2.py 中“更改”library1 导入(不仅是 1 个变量),因此结果输出将为“2”
(也就是说,将library2.py中library1的缓存替换为library3)
你可以使用复制
import copy
b = copy.copy(lib1.a)
...
print(lib2.b)
我找到了一种方法:
import library1,library2,library3
import importlib
for i in library3.__dict__.keys():
library1.__dict__[i] = library3.__dict__[i]
library2 = importlib.reload(library2)
警告:此方法非常 hacky,你可能可能会破坏东西。
假设我们有这个 library1.py
:
var1 = 100
var2 = 'never gonna give you up'
a = 3.1415926
而且,我们想用overwrite.py
覆盖它:
var1 = -9999
var2 = 'never gonna let you down'
a = 2.71828
如果我们进入 shell,我们可以看到一个模块有一个 __dict__
属性,它包含它内部的所有内容。
>>> import library1
>>> library1.__dict__
# NOTE: This also contains a bunch of python's variables, including their builtins, magic things like `__name__`, etc
# I cut them out for simplicity
{'var1': 100, 'var2': 'never gonna give you up', 'a': 3.1415926}
这很好,因为我们可以使用它来访问属性而无需真正访问它们:
>>> import library1
>>> library1.__dict__['a'] = 'never gonna run around and desert you'
>>> library1.a
'never gonna run around and desert you'
>>> library1.__dict__['this_variable_wasnt_even_defined'] = 'never gonna make you cry'
>>> library1.this_variable_wasnt_even_defined
'never gonna make you cry'
我们不想覆盖任何魔法(以两个下划线开头和结尾)属性,所以:
>>> def is_magic(name: str) -> bool:
... return name[0] == '_' and name[1] == '_' and name[-1] == '_' and name[-2] == '_'
>>> is_magic('not_very_magic_variable')
False
>>> is_magic('__name__')
True
>>> is_magic('__init__')
True
我们也不想覆盖任何内置函数:
>>> def is_builtin(obj: object) -> bool:
... builtin_type = type(print)
... return obj.__class__ is builtin_type
...
>>> is_builtin(print)
True
>>> is_builtin(open)
True
这就是一切汇集的地方。
我们使用 library3
中的值覆盖 library1
的 __dict__
。
>>> from utils import is_builtin, is_magic
>>> import library1
>>> import overwrite
>>>
>>> for key, value in overwrite.__dict__.items():
... if is_magic(key):
... continue
... if is_builtin(value):
... continue
... # otherwise, we have something to overwrite
... library1.__dict__[key] = value
... print(f'I have overwritten {key} with {value}')
...
I have overwritten var1 with -9999
I have overwritten var2 with never gonna let you down
I have overwritten a with 2.71828
可以看到library1
已经被覆盖了:
# ...
>>> library1.var1
-9999
>>> library1.var2
'never gonna let you down'
>>> library1.a
2.71828
假设,我们有 3 个文件:
library1.py:
SomeVariable = '1'
library2.py:
import library1
print(library1.SomeVariable)
library3.py:
SomeVariable = '2'
我的目标是在 library2.py 中“更改”library1 导入(不仅是 1 个变量),因此结果输出将为“2” (也就是说,将library2.py中library1的缓存替换为library3)
你可以使用复制
import copy
b = copy.copy(lib1.a)
...
print(lib2.b)
我找到了一种方法:
import library1,library2,library3
import importlib
for i in library3.__dict__.keys():
library1.__dict__[i] = library3.__dict__[i]
library2 = importlib.reload(library2)
警告:此方法非常 hacky,你可能可能会破坏东西。
假设我们有这个 library1.py
:
var1 = 100
var2 = 'never gonna give you up'
a = 3.1415926
而且,我们想用overwrite.py
覆盖它:
var1 = -9999
var2 = 'never gonna let you down'
a = 2.71828
如果我们进入 shell,我们可以看到一个模块有一个 __dict__
属性,它包含它内部的所有内容。
>>> import library1
>>> library1.__dict__
# NOTE: This also contains a bunch of python's variables, including their builtins, magic things like `__name__`, etc
# I cut them out for simplicity
{'var1': 100, 'var2': 'never gonna give you up', 'a': 3.1415926}
这很好,因为我们可以使用它来访问属性而无需真正访问它们:
>>> import library1
>>> library1.__dict__['a'] = 'never gonna run around and desert you'
>>> library1.a
'never gonna run around and desert you'
>>> library1.__dict__['this_variable_wasnt_even_defined'] = 'never gonna make you cry'
>>> library1.this_variable_wasnt_even_defined
'never gonna make you cry'
我们不想覆盖任何魔法(以两个下划线开头和结尾)属性,所以:
>>> def is_magic(name: str) -> bool:
... return name[0] == '_' and name[1] == '_' and name[-1] == '_' and name[-2] == '_'
>>> is_magic('not_very_magic_variable')
False
>>> is_magic('__name__')
True
>>> is_magic('__init__')
True
我们也不想覆盖任何内置函数:
>>> def is_builtin(obj: object) -> bool:
... builtin_type = type(print)
... return obj.__class__ is builtin_type
...
>>> is_builtin(print)
True
>>> is_builtin(open)
True
这就是一切汇集的地方。
我们使用 library3
中的值覆盖 library1
的 __dict__
。
>>> from utils import is_builtin, is_magic
>>> import library1
>>> import overwrite
>>>
>>> for key, value in overwrite.__dict__.items():
... if is_magic(key):
... continue
... if is_builtin(value):
... continue
... # otherwise, we have something to overwrite
... library1.__dict__[key] = value
... print(f'I have overwritten {key} with {value}')
...
I have overwritten var1 with -9999
I have overwritten var2 with never gonna let you down
I have overwritten a with 2.71828
可以看到library1
已经被覆盖了:
# ...
>>> library1.var1
-9999
>>> library1.var2
'never gonna let you down'
>>> library1.a
2.71828