Private class variables (Python)
From LiteratePrograms
Python does not have the concept of private class variables, offering only name-mangling to discourage internal methods from being called from outside the class.
However, Python does have lexical scoping, and with some clever trick one can get the benefits of private class variables.
In the code example below, we use the common example of a bank account class. The operations that are accessible to the public is get_balance, deposit and withdraw; the latter would fail if there are insufficient funds.
<<bank_account.py>>= class account(object): def __init__(self, amount): private_vars private_methods class_methods instance_methods
<<private_vars>>= privates = { 'balance' : amount }
The private variables need to be contained within a mutable object, otherwise attempts to modify it from a method would result in the creation of a local variable with the same name.
I use a dictionary here, but you can use a list as well. The advantage of using a dictionary is that it is more readable when you have many private variables.
<<private_methods>>= ''' set_balance is a private method it is only visible from other methods declared in the constructor ''' def set_balance(new_balance): privates['balance'] = new_balance
set_balance should be kept private, since it can set the bank balance to an arbitrary amount. By defining it inside the constructor and not attaching it to either the class or the method, we ensure that it can only be called by other methods we also define inside the constructor.
<<instance_methods>>= ''' get_balance is attached to the instance of the class, so it does not need to take the object self, since it is in the lexical scope ''' def get_balance(): return privates['balance'] self.get_balance = get_balance def deposit(amount): bal = set_balance(get_balance() + amount) self.deposit = deposit
Here are so-called instance methods. Note that they behave the same way as class methods, even though we attach them to the object instantiated from the class (self) rather than the class itself.
<<class_methods>>= ''' withdraw is a more normal Python class method ''' def withdraw(self, amount): bal = get_balance() if bal >= amount: bal = set_balance(bal - amount) return True else: return False account.withdraw = withdraw
And class methods.
The only difference between the two is that if you try dir(account) after creating at least one object, the class methods will show up but the instance methods would not. It is probably preferable to use class methods for this reason.
Download code |