Sup, i'm doing a little account registration just for learning propose.
I created a class called Accounts and did many different functions to work with. With previous acknowledgment i knew that i need to start them from a function called 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()
is working fine, i tested a print(self.contas)
in the end of it and it printed all accounts from inside my x.txt. The problem start when i need to call accountsprinting()
, i tried to start it with print(self.contas)
but shows me a empty dictionary, which means it is not accessing the "new" self.contas
. I did the exact samething in a different type of project and it worked fine, i know i'm missing something really obvious here, so i'm asking sorry beforehand for my lack of attention.
Thanks for your time, good codding.
EDIT 1
People asked for the entire program, this is my entire program. I'm using PyCharm, i created this as a accounts.py
, a root file or resources file, and i'm going to be importing this class to another main.py
to use the respective functions. I know i must call Accounts().getaccounts()
first, then i must call the other functions, so i can first fill my "accounts database". Even doing this:
Adding print(self.contas)
to the end of getaccounts()
and the start of accountsprinting()
And doing on the same .py:
Account().getaccounts()
Account().accountsprinting()
Or doing on different .py:
from AccountManager import Account
Account().getaccounts()
Account().accountsprinting()
The output is the same:
{'Bruno': '666', 'Bruno2': '444', 'Pedro': '2222a', 'Breno': '092b'}
{}
EDIT 2
Adding self.getaccounts()
to def __init__(self)
as @Darkonaut said, really worked, on the same .py and even doing an import from another .py, but i would like to understand why without it, it doesn't work, makes no sense to me.
Thanks a lot =)
You forgot self.getaccounts()
in the last line of your __init__
method, hence contas remains empty because it never get's filled.
TL;DR Make sure you keep a reference to a newly created instance to keep it alive and perform following method calls on this instance.
__init__
is a method which is being called after an instance get's created
and initializes the instance. You create an instance of a class every time
you call a class like you did with Account()
.
But if you don't keep a (external) reference to this newly created instance, you can't address the instance to invoke further methods on it. What happens in your code:
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
Both instances are quickly garbage collected (CPython implementation of Python assumed), because you don't hold an external reference to them, like you would do if you assign a new instance to a name like: acc = Account()
.
You can check that you get a new object every time you call Account()
by comparing identity with Account(1) is Account(1) # False
or by looking at the id
numbers:
id(Account(1))
# 88311904
id(Account(1))
# 88312408
As a side note:
It doesn't have to be a named reference like acc
above, you could also hold an
implicit, unnamed reference by placing the new instances in a list for example and the list would keep the reference to the instances and thus, keeping them alive:
class Account:
def __init__(self, x):
self.x = x
lst = [Account(1), Account(2)]
lst[0].x
# 1
lst[1].x
# 2
self
in your code is an (internal) reference connecting (binding) class and instance.
If you assign to self
like you do with self.contas[login] = senha
within your instance-method getaccounts
, you do this only for the actual instance where you are calling getaccounts
upon. So when you call Account().getaccounts()
and
later Account().accountsprinting()
you are doing this for two different
instances and not on the same. Hence the second instance has an empty contas
dict because for this instance you didn't call getaccounts()
before.