Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python nested classes

First of all, here's my test code, I'm using python 3.2.x:

class account:
    def __init__(self):
        pass

    class bank:
        def __init__(self):
            self.balance = 100000

        def balance(self):
            self.balance

        def whitdraw(self, amount):
            self.balance -= amount

        def deposit(self, amount):
            self.balance += amount

when I do:

a = account()
a.bank.balance

I expected to get the value of balance returned, instead I get the function "balance", why is this? It returns the value of balance when I do:

class bank:
    def __init__(self):
        self.balance = 100000

    def balance(self):
        self.balance

    def whitdraw(self, amount):
        self.balance -= amount

    def deposit(self, amount):
        self.balance += amount

a = bank()
a.balance

So I want to know why this is and it would be great if someone could come up with a way to give me the value of balance in the nested version.

like image 876
Daquicker Avatar asked Jan 30 '13 14:01

Daquicker


People also ask

Does Python have nested classes?

A class defined in another class is known as an inner class or nested class. If an object is created using child class means inner class then the object can also be used by parent class or root class.

Can we write class inside a class in Python?

You can have more than one inner class in a class. As we defined earlier, it's easy to implement multiple inner classes. class Outer """Outer Class""" def __init__self ## Instantiating the 'Inner' class self. inner self.

Does Python support inner classes?

What are inner (nested) classes in Python? You are probably already familiar with object oriented programming and the concept of a Python class. Just as you can create a function within a function, in Python, you can create a class inside of a class.


3 Answers

My version of your code, with comments:

#
# 1. CamelCasing for classes
#
class Account:
    def __init__(self):
        # 2. to refer to the inner class, you must use self.Bank
        # 3. no need to use an inner class here
        self.bank = self.Bank()

    class Bank:
        def __init__(self):
            self.balance = 100000

        # 4. in your original code, you had a method with the same name as 
        #    the attribute you set in the constructor. That meant that the 
        #    method was replaced with a value every time the constructor was 
        #    called. No need for a method to do a simple attribute lookup. This
        #    is Python, not Java.

        def withdraw(self, amount):
            self.balance -= amount

        def deposit(self, amount):
            self.balance += amount

a = Account()
print(a.bank.balance)
like image 177
codeape Avatar answered Oct 16 '22 23:10

codeape


There are several problems:

  1. You're using the name balance for both the data member and for the function.
  2. You're missing a return statement in balance().
  3. balance() operates on an instance of bank. There is no instance in a.bank.balance: here, a.bank refers to the inner class itself.
like image 20
NPE Avatar answered Oct 16 '22 23:10

NPE


a.bank is the class (not instance) since you've never created an instance of the bank on a. So if a.bank is a class, a.bank.balance is a method bound to that class.

This works however:

class account:
    def __init__(self):
        self.bank = account.bank()

    class bank:
        def __init__(self):
            self.balance = 100000

        def whitdraw(self, amount):
            self.balance -= amount

        def deposit(self, amount):
            self.balance += amount

a = account()
print a.bank.balance

Of course, as you show working code without nested classes, It really begs the question about why you want to use nested classes for this. I would argue that the non-nested version is much cleaner.

like image 45
mgilson Avatar answered Oct 16 '22 23:10

mgilson