在Python类的特殊行为 [英] Peculiar behavior of Classes in Python

查看:178
本文介绍了在Python类的特殊行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习Python的,但没有OOP经验。我进入IDLE以下行(Python的3​​.3),和对象的行为是困惑我:

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
<class '__main__.IBAN.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
>>> 

为什么对象的ISO code属性 numberTwo IBAN ,但不一样的物体的ISO code 的Numberone

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

我希望是这样的:

>>> 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.

有人能解释或连结解释阶层的Python中的行为的资源?我试着学习Python的教程和统一类型和类在Python 2.2 由Guido van Rossum的,但我无法理解他们在说什么。

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.

感谢您!

推荐答案

类是不同的对象不是类的实例。类有属性和实例有属性。每当你尝试访问一个实例的属性,如果实例不具有的属性,它抬头的类。如果你的设置的上一个实例的属性,它总是被设置上的实例,即使这意味着它阴影相同名称的属性上的类。

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.

在你的类IBAN,你定义的 ISO code 上的的一个属性。当你做 numberOne.ISO code ='ES',您设置的新的的上的实例属性的。您已经从 IBAN.ISO code 的价值脱钩 numberOne.ISO code 的价值。但是,你创建(如 numberTwo )的任何新的实例仍然没有自己的实例ISO code。当你再设置 IBAN.ISO code ,要更改的的属性。

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.

您可以把类属性像一个默认的。当你做 obj.attr ,如果 OBJ 不具有其自己的属性 ATTR ,它需要的价值这个类的在那一刻的。如果您更改类的属性值,您更改默认;如果以后尝试访问不具有其自己的属性对实例的属性,他们将看到您创建新的默认。

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'

现在我将在类设置一个新值。这不会影响有一个,因为有一个有其自身的价值。但是,由于两个不具有其自身的价值,它正从类它的价值,因为我改变了类的价值,这改变什么价值,我从<$得到C $ C>两个

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'

要记住的是,权当你这样做的每一个属性的查找总是动态计算。创建一个实例不会自动复制类从类实例的属性。当您在一个实例访问一个属性,该实例本身说:难道我有我自己的这个name属性?如果是的话,返回值,如果没有,返回类的价值。它要求这本身的每次的您试图访问一个属性;没有一刻在该实例成为一流的独立。

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.

这篇关于在Python类的特殊行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆