一切都是一个对象甚至工作如何?

时间:2014-10-10 08:24:24

标签: python oop

我理解 Everything is a Object 背后的主要理论,但我真的不明白它是如何在幕后实现的。

功能

所以:foo(4)foo.__call__(4)相同。但是什么阻止我做foo.__call__.__call__(4)

foo是一个函数,foo.__call__...是函数的所有方法包装器,但是当我调用一个函数时,甚至调用了哪些函数?

所有这些属性

我的foo函数有很多属性,每个对象都存储了很多属性,那么它如何不占用无限的内存呢?

sys.getsizeof('a')生成22,对于一个字符来说似乎相当大,但是因为它引用了71个属性而非常小。

我想我要问的是,如果我想实现一个天真的python版本(我不是,但它似乎是最好的问题)我将如何实现它?

修改1 我对builtins进行了一些了解,并意识到它们引用了相同的属性(id('a'.upper) == id('b'.upper))。这让我问它是如何知道它正在访问的对象?

修改2 作为pts points out 'a'.upper is not 'b'.upper,以便清除它。

我看过source for IronPython因为我认为它会帮助我理解,但它让我更加困惑。

4 个答案:

答案 0 :(得分:10)

我认为你感到困惑的是,尽管所有Python的变量都可能是对象,并且这些变量的所有属性都可能是对象,但是存在限制。我的意思是,对于正常的类,结构通常是:

myclass -> classobj -> type

如果你在控制台中尝试这个,你可以看到:

>> class A:
..    pass
..

>> print type(A)
<type 'classobj'>
>> print type(type(A))
<type 'type'>

但如果您尝试深入type,则只需获得typetype是Python中所有对象的基础对象。

>> print type(type(type(A)))
<type 'type'>
>> print type(type(type(type(type(A)))))
<type 'type'>

您不仅获得相同的基类/对象类型,而且您为A的类实例获得该类型的相同实例,因此尽管您可以对函数type进行无限递归(即。type(type(type(type(... ))))),你不会去任何地方(即没有探索无限记忆的无底洞。)

>> id(type(type(type(A)))
505578544
>> id(type(type(type(type(A))))
505578544

同样的原则适用于Python中的所有对象以及Python中对象的所有属性,因为它们也是对象,但它们都是有限的。

回答你之前的一个问题,

  

foo.__call__与'{1}}

的'method-wrapper'实例相同

所以没有什么可以阻止你用foo.__call__.__call__ ......

做很长的路线

Python对你起了一个作用,因为foo.__call__.__call__.__call__为'method-wrapper'提供了一个实例,在'method-wrapper'类中有一个函数/变量,也称为foo.__call__到该类的同一个实例。

答案 1 :(得分:2)

您认为如果所有内容都是对象,则foo(4)必须自动转换为foo.__call__(4)是错误的。

Python首先可以检查对象foo是否是一个函数,如果是,则调用它,然后执行其他操作(比如查找__call__属性)。

答案 2 :(得分:1)

您可以将“对象”视为指向其数据成员字典的指针,并指向其类型的数据成员字典(通常包括该类型的方法)。这些通常是有限空间,类型的所有对象共享类型的字典。 (这是一种过度简化,但可能足以理解为什么它不是无限的记忆)。

答案 3 :(得分:1)

id异常是由早期引用计数引起的:Python内存管理器过早释放'a'.upper,然后'b'.upper被分配到相同的内存地址。

早免费:

>>> id('a'.upper), id('b'.upper)
(3073677900L, 3073677900L)

没有早期免费:

>>> x, y = 'a'.upper, 'b'.upper
>>> id(x), id(y)
(3073678252L, 3073677900L)
>>> x, y
(<built-in method upper of str object at 0xb7317b20>, <built-in method upper of str object at 0xb7317b40>)

参考比较:

>>> 'a'.upper is 'b'.upper
False