python的特殊类,在Python类的特殊行为

I'm learning Python, but have no OOP experience. I'm entering the following lines in IDLE (Python 3.3), and the behavior of the objects is confusing me:

>>> class IBAN:

ISOcode = ' '

checkDigits = '00'

class CCC:

bankCode = '0000'

branchCode = '0000'

checkBank = '0'

checkAccount = '0'

account = '0000000000'

>>> >>> numberOne = IBAN()

>>> numberOne.CCC

>>> numberOne.CCC.bankCode

'0000'

>>> numberOne.ISOcode = 'ES'

>>> IBAN.ISOcode

' '

>>> numberOne.ISOcode

'ES'

>>> IBAN.ISOcode = 'FR'

>>> numberOne.ISOcode

'ES'

>>> IBAN.ISOcode = 'FR'

>>> IBAN.ISOcode

'FR'

>>> numberTwo = IBAN()

>>> numberTwo.ISOcode

'FR'

>>> IBAN.ISOcode = 'IT'

>>> IBAN.ISOcode

'IT'

>>> numberOne.ISOcode

'ES'

>>> numberTwo.ISOcode

'IT'

>>> IBAN.ISOcode is numberTwo.ISOcode

True

>>>

Why is the ISOcode attribute of object numberTwo the same as the ISOcode of IBAN, but not the same as the ISOcode of objectnumberOne?

I expected something like this:

>>> numberOne.ISOcode

'ES'

>>> numberTwo.ISOcode

'FR'

This, however, doesn't match my results.

I found a similar question on StackOverflow, that made me think the results should be:

>>> numberOne.ISOcode

'IT'

>>> numberTwo.ISOcode

'IT'

But that doesn't match my results either.

Can anybody explain or link to resources that explain the behavior of Classes in Python? I tried to study the Python Tutorial and "Unifying types and classes in Python 2.2" by Guido van Rossum, but I wasn't able to understand what they were saying.

Thank you!

解决方案

The class is a different object than instances of the class. Classes have attributes, and instances have attributes. Every time you try to access an attribute of an instance, if the instance does not have the attribute, it is looked up on the class. If you set an attribute on an instance, it is always set on the instance, even if that means it shadows an attribute of the same name on the class.

In your class IBAN, you defined an attribute ISOcode on the class. When you do numberOne.ISOcode = 'ES', you set a new attribute on the instance. You have decoupled the value of numberOne.ISOcode from the value of IBAN.ISOcode. But any new instances you create (like numberTwo) will still not have their own instance ISOcode. When you then set IBAN.ISOcode, you are changing the class attribute.

You can think of the class attribute as like a "default". When you do obj.attr, if obj does not have its own attribute attr, it takes the value that the class has at that moment. If you change the value of class's attribute, you change the default; if you later try to access the attribute on an instance that doesn't have its own attribute, they will see the new default that you created.

Here is a somewhat more streamlined example:

>>> class Foo(object):

... attr = "Something"

>>> one = Foo()

>>> two = Foo()

At first, all have the same value, because I didn't specify any instance-specific values, so one and two both get their value from the class.

>>> Foo.attr

'Something'

>>> one.attr

'Something'

>>> two.attr

'Something'

Now I will set a new value just for one. This does not affect Foo, and two is still gettings its value from Foo, so two is also not affected.

>>> one.attr = "This is only for #1"

>>> Foo.attr

'Something'

>>> one.attr

'This is only for #1'

>>> two.attr

'Something'

Now I will set a new value on the class Foo. This doesn't affect one, because one has its own value. But since two doesn't have its own value, it is getting its value from the class, and since I changed the class's value, this changes what value I get from two:

>>> Foo.attr = "This is the class value"

>>> Foo.attr

'This is the class value'

>>> one.attr

'This is only for #1'

>>> two.attr

'This is the class value'

The thing to remember is that every attribute lookup is always dynamically computed right when you do it. Creating an instance does not automatically copy class attributes from the class to the instance. When you access an attribute on an instance, the instances says to itself "Do I have my own attribute with this name? If so, return that value. If not, return the class's value." It asks itself this every time you try to access an attribute; there is no moment at which the instance becomes "independent" of the class.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值