如何替换导入库中的导入?

发布于 2025-01-23 15:52:18 字数 337 浏览 2 评论 0原文

假设我们有3个文件:

library1.py:

SomeVariable = '1'

library2.py:

import library1
print(library1.SomeVariable)

library3.py:

SomeVariable = '2'

我的目标是“更改” library1 import(不仅是1个变量),因此结果输出将为'2' (换句话说,替换Library1中的Library1的缓存2.Py中的Library3)

Suppose, we have 3 files:

library1.py:

SomeVariable = '1'

library2.py:

import library1
print(library1.SomeVariable)

library3.py:

SomeVariable = '2'

my goal is to "change" library1 import(not only 1 variable) in library2.py so result output will be '2'
(in other words,replace cache of library1 in library2.py to library3)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

暖心男生 2025-01-30 15:52:18

警告:此方法是非常 hacky的,您的可能会破坏东西。


假设我们有此library1.py

var1 = 100
var2 = 'never gonna give you up'
a = 3.1415926

并且,我们想用oferwrite.py.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中使用值来覆盖__ dict __ library1的。

>>> 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

WARNING: This method is very hacky, and you might probably will break things.


Let's say we have this library1.py:

var1 = 100
var2 = 'never gonna give you up'
a = 3.1415926

And, we want to overwrite it with overwrite.py:

var1 = -9999
var2 = 'never gonna let you down'
a = 2.71828

If we go into a shell, we can see that a module has a __dict__ attribute that holds everything it has inside of it.

>>> 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}

This is nice, since we can use this to access the attributes without really accessing them:

>>> 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'

We don't want to overwrite any magic (starting and ending with two underscores) attributes, so:

>>> 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

We also don't want to overwrite any builtin functions:

>>> def is_builtin(obj: object) -> bool:
...     builtin_type = type(print)
...     return obj.__class__ is builtin_type
... 

>>> is_builtin(print)
True
>>> is_builtin(open)
True

This is where it all comes together.

We use values in library3 to overwrite the __dict__ of library1.

>>> 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

You can see that library1 has been overwritten:

# ...
>>> library1.var1
-9999
>>> library1.var2
'never gonna let you down'
>>> library1.a
2.71828
南风几经秋 2025-01-30 15:52:18

我找到了一种方法:

import library1,library2,library3
import importlib

for i in library3.__dict__.keys():
    library1.__dict__[i] = library3.__dict__[i]
library2 = importlib.reload(library2)

I found one way to do that:

import library1,library2,library3
import importlib

for i in library3.__dict__.keys():
    library1.__dict__[i] = library3.__dict__[i]
library2 = importlib.reload(library2)
生活了然无味 2025-01-30 15:52:18

您可以使用副本

import copy
b = copy.copy(lib1.a)
...
print(lib2.b)

You can use copy

import copy
b = copy.copy(lib1.a)
...
print(lib2.b)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文