来自 __init__ 的变量在一个函数中更改,但未被识别为已更改为其他函数

Variable from __init__ changed in one function, but not recognized as changed to other function

Sup,我正在注册一个小帐户,只是为了学习提议。 我创建了一个名为 Accounts 的 class 并执行了许多不同的功能。通过先前的确认,我知道我需要从一个名为 def __init__(self)

的函数启动它们
class Account:
    def __init__(self):
        self.contas = {}
        self.bancodecontas = open("x.txt", 'r')

    def getaccounts(self):
        for linha in self.bancodecontas:
            linha = linha.strip()
            conta = linha.split(",")
            login = conta[0]
            senha = conta[1]
            self.contas[login] = senha

    def accountsprinting(self):
        for login, senha in self.contas.items():
            print("Login= ", login, "Senha= ", senha)

getaccounts() 工作正常,我在它的末尾测试了一个 print(self.contas),它打印了我的 x.txt 中的所有帐户。当我需要调用 accountsprinting() 时,问题就开始了,我试图用 print(self.contas) 启动它,但显示了一个空字典,这意味着它没有访问 "new" self.contas。我在不同类型的项目中做了完全相同的事情并且效果很好,我知道我在这里遗漏了一些非常明显的东西,所以我事先对我缺乏关注表示歉意。 感谢您的时间,好的编码。

EDIT 1

有人要整个程序,这是我的整个程序。我正在使用 PyCharm,我将它创建为 accounts.py,一个根文件或资源文件,我将把这个 class 导入另一个 main.py使用各自的功能。我知道我必须先调用 Accounts().getaccounts(),然后我必须调用其他函数,所以我可以先填充我的 "accounts database"。即使这样做:

print(self.contas) 添加到 getaccounts() 的末尾和 accountsprinting()

的开头

并在同一个 .py 上做:

Account().getaccounts()
Account().accountsprinting()

或者在不同的 .py 上做:

from AccountManager import Account
Account().getaccounts()
Account().accountsprinting()

输出是一样的: {'Bruno': '666', 'Bruno2': '444', 'Pedro': '2222a', 'Breno': '092b'} {}

EDIT 2

如@Darkonaut 所说,将 self.getaccounts() 添加到 def __init__(self),确实有效,在同一个 .py 上,甚至从另一个 .py 导入,但我想了解为什么没有它,它不起作用,对我来说没有意义。 非常感谢 =)

您在 __init__ 方法的最后一行忘记了 self.getaccounts(),因此 contas 仍然是空的,因为它永远不会被填充。


TL;DR 确保您保留对新创建实例的引用以使其保持活动状态 并在 this 实例上执行以下方法调用。

__init__ 是在创建实例后调用的方法 初始化实例。您每次都创建一个 class 的实例 你调用 class 就像调用 Account().

但是如果您不保留对这个新创建实例的(外部)引用, 您无法对实例进行寻址以在其上调用更多方法。您的代码中发生了什么:

Account().getaccounts() # new instance of Account created,
# i.a. __init__ called, finally getaccounts called

Account().accountsprinting() # new instance of Account created,
# i.a. __init__ called, finally accountsprinting called

这两个实例都很快被垃圾回收(假定 Python 的 CPython 实现),因为您没有对它们的外部引用,就像您分配新实例时所做的那样像这样的名字:acc = Account().

您可以通过将身份与 Account(1) is Account(1) # False 进行比较或查看 id 数字来检查每次调用 Account() 时是否获得了一个新对象:

id(Account(1))
# 88311904
id(Account(1))
# 88312408

旁注:

它不必像上面的 acc 那样是一个命名引用,你也可以持有一个 例如,通过将新实例放在列表中来隐式、未命名引用,列表将保留对实例的引用,从而使它们保持活动状态:

class Account:
    def __init__(self, x):
        self.x = x

lst = [Account(1), Account(2)]
lst[0].x
# 1
lst[1].x
# 2

self 在您的代码中是一个(内部)参考连接(绑定)class 和实例。 如果您像在实例方法 getaccounts 中分配给 self 一样分配给 self.contas[login] = senha,您只对您所在的 actual 实例执行此操作打电话给 getaccounts。所以当你打电话给 Account().getaccounts() 和 稍后 Account().accountsprinting() 你正在为两个不同的人做这个 实例和不一样。因此,第二个实例有一个空的 contas 字典,因为对于 this 实例,您之前没有调用 getaccounts()

您需要创建并使用同一个实例来调用这两种方法并获得预期结果。

acc = Account()
accounts = acc.getaccounts()
acc.accountsprinting()

此外,您导入 Accounts 但在代码中调用 Account