Python 嵌套类

17 投票
3 回答
33522 浏览
提问于 2025-04-17 14:12

首先,这是我的测试代码,我使用的是 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

当我这样做时:

a = account()
a.bank.balance

我本来期待能得到余额的值返回,结果却得到了函数“balance”,这是为什么呢?当我这样做时,它会返回余额的值:

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

所以我想知道这是为什么,如果有人能想出一种方法让我在嵌套版本中得到余额的值,那就太好了。

3 个回答

1

a.bank 是一个(不是实例),因为你从来没有在 a 上创建过 实例。所以如果 a.bank 是一个类,那么 a.bank.balance 就是绑定在这个类上的一个方法。

不过,这样的写法是可以的:

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

当然,正如你展示的那段没有嵌套类的代码,这就引出了一个问题:你为什么想用嵌套类呢?我认为不使用嵌套类的版本要干净得多。

10

这里有几个问题:

  1. 你把 balance 这个名字同时用在了数据成员和函数上。
  2. balance() 里缺少一个 return 语句。
  3. balance() 是在一个 实例bank 上操作的。但是在 a.bank.balance 中没有实例:这里的 a.bank 指的是内部类本身。
31

这是我对你代码的版本,并加了一些注释:

#
# 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)

撰写回答