【问题标题】:Variable from __init__ changed in one function, but not recognized as changed to other function来自 __init__ 的变量在一个函数中更改,但未被识别为更改为其他函数
【发布时间】:2018-01-22 19:33:13
【问题描述】:

Sup,我正在做一个小帐户注册只是为了学习建议。 我创建了一个名为 Accounts 的类,并使用了许多不同的功能。有了之前的确认,我知道我需要从一个名为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) 开始它,但显示的是一个空字典,这意味着它没有访问“新”self.contas。我在不同类型的项目中做了完全相同的事情并且效果很好,我知道我在这里遗漏了一些非常明显的东西,所以我事先为我缺乏关注而道歉。 感谢您的时间,良好的编码。

编辑 1

人们要求整个程序,这是我的整个程序。我正在使用 PyCharm,我将其创建为 accounts.py、根文件或资源文件,我将把这个类导入另一个 main.py 以使用相应的功能。我知道我必须先调用Accounts().getaccounts(),然后我必须调用其他函数,所以我可以先填写我的“帐户数据库”。即使这样做:

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

编辑 2

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

【问题讨论】:

  • 请提供一个简短的完整程序来演示错误。请参阅minimal reproducible example 了解更多信息。
  • 例如,当我创建一个short complete program 时,它工作正常。由于您发布的代码可以正常工作,因此问题一定出在您没有发布的代码上。

标签: python function class dictionary object-oriented-database


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢,我编辑了,你能看到我对上面答案的最后评论吗?我评论了我对它的理解,如果我是正确的,你能说一下吗?
【解决方案2】:

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


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

__init__ 是在创建实例后调用的方法 并初始化实例。您每次都创建一个类的实例 您可以像使用 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 在您的代码中是连接(绑定)类和实例的(内部)引用。 如果您像在您的实例方法getaccounts 中分配self.contas[login] = senha 一样分配给self,那么您只对调用getaccounts实际 实例执行此操作。所以当你打电话给Account().getaccounts() 和 稍后Account().accountsprinting() 你这样做是为了两个不同的 实例和不一样。因此,第二个实例有一个空的 contas dict,因为对于 this 实例,您之前没有调用 getaccounts()

【讨论】:

  • 他在初始化一个新对象后仍然可以调用getaccounts()。由于他没有展示完整的程序,我猜他不是在创建对象,而是直接从类中调用方法。
  • @A Magoon 如果他愿意这样做,他可能不必担心空 contas,除非文件是空的。
  • 它有效,但正如@AMagoon 所说,我仍然可以调用 getaccounts(),然后在调用 accountsprinting() 之后它应该有效,我的问题是,为什么 accountsprinting() 不使用新的getaccounts() “做了”的 self.contas
  • @Bruno Cerk 每次调用Account() 时,您都会创建一个新实例,因此每次都会在不同的实例上调用这些方法。实例化一个帐户account = Account(),然后对此进行所有后续方法调用:account.getaccounts() 等等...
  • 那么我做 account = Account() 我很想说 account.getaccounts() 和 account.accountsprinting() 在同一个实例上,如果我不成功,getaccounts( ) 将发生在某种“Instance1”和“Instance 2”上的 accountsprinting() 上,所以在实例 2 上,我的数据库是空的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多