繁体   English   中英

从另一个模块看不到对 static class 变量的更改

[英]Changes to static class variable are not visible from another module

我正在为一些 REST ZDB974238714CA8DE63ZA7CED1 To make it easier to manipulate the state of the objects I get from the API, I want to store a static reference to my API client instance. 假设我有一个文件user.py

class User:
    _client: Client = None

因此,当客户端第一次成功通过身份验证时,我更新了引用:

class Client:
    def authenticate(self):
        ...
        User._client = self

这发生在我的client.py文件中。 现在我可以从client.py中声明的任何 function 成功访问User._client ,但是当我从另一个模块尝试相同的事情时, User._client仍然是None

假设这是我的文件夹结构

└── my_api_client
    ├── __init__.py
    ├── client.py
    ├── search.py
    └── user.py

然后,当我从search.py 中的 function 调用User._client时,我得到None而不是对当前客户端实例的引用。

我在创建一个演示此问题的最小工作示例时遇到了麻烦,所以也许我只是在导入时弄乱了一些东西。 如果我从另一个模块导入 class 并且如果对 class 的 static 属性的引用在所有模块之间共享,我认为如果我更好地理解会发生什么,这将真的很有帮助。 如果确实如此,我做错了什么?

我试图重现你的问题,但不能。

# user.py

print("defining class User")


class User:
    _client = None  # removed type annotation here to prevent circular import


print("right now, User._client is " + repr(User._client))
# client.py

import user


class Client:
    def authenticate(self):
        user.User._client = self


print("instantiating a Client")
client = Client()
print("before athenticating, the User._client is " + repr(so70744003_user.User._client))
client.authenticate()
print("before athenticating, the User._client is " + repr(so70744003_user.User._client))

并运行文件client.py

defining class User
right now, User._client is None
instantiating a Client
before athenticating, the User._client is None
before athenticating, the User._client is <__main__.Client object at 0x7fc1816a9b20>

我可以给你详细说明发生了什么:

  • Python 获得了文件client.py所以开始运行文件中的代码
  • 它以import user开头,因此 Python 将搜索user模块并加载它
    • Python 没有内置user模块,因此它会在其sys.path目录中搜索它,并找到匹配的文件
    • Python starts running the user.py file, which defines a User class, so it instantiates a class instance for it (with a static member _client set to None ), and binds it to the User name in the current module
    • 然后它打印出User的 static 成员_client确实是None
    • 运行完user.py文件后,Python 继续运行client.py文件
  • 导入成功,所以 Python 有一个module object 并将其绑定到当前模块 scope ( client )中的user
  • 继续运行文件,遇到 class 定义(定义了一个方法),它被绑定到当前模块中的Client名称
  • 然后它实例化一个Client并将其绑定到当前模块中的client名称(也命名为client
  • 然后它调用authenticate ,它将user (指向从user.py ._client .User类中的 static 变量)设置为self
  • 最后它打印出 static 变量 new value 实际上是Client的一个实例

在您的问题评论中,建议使用global变量。 它不会改变任何事情,因为您的User class 本质上已经是singleton (只有一个声明),您只是碰巧访问了它的一个字段。 单身人士的字段也可以视为 singleton 值。

我不知道你的实现有什么问题,你没有给我们足够的东西来找到错误。 如果您想找到它,我建议尝试将其简化为Minimal Reproducible Example 通常在这个过程中,你会自己找到解决方案。

我担心这可能是由相互导入引起的,因此变量的 state 取决于项目每个文件中导入语句的顺序。 这是尝试打破周期或在它们周围小心的理由。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM