python中修改类定义的有趣现象

来源:互联网 发布:淘宝网店客服培训 编辑:程序博客网 时间:2024/05/21 12:51

最近在学习python,写下一些心得,作为以后的回顾。

 

都说python是动态语言,以前一直没理解动态的真正含义。。。在学了几天python后,结合自己对javascript的理解。。。终于开始慢慢体会到“动态”的意思了。

动态的主要体现是在类型的动态上面,也就是类型是在“运行的时候定义,并且可以动态改变定义的”。这是我的理解和体会,不知道真正的动态性定义是怎样。

例如,c++/C#/java等静态语言,定义一个类型以后,这个类型在运行的时候是不可以改变定义的,虽然C#还提供有运行时后动态定义类的功能,但是却不能做到动态改变。但是python就可以。看我下面的一个有趣实验:

 

Python 3.2.2 (default, Sep  4 2011, 09:51:08) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.

#定义一个类,一个类实例方法
>>> class MyClass():
 def func(self):
  print("old class")

  

#类实例,调用方法
>>> inst=MyClass()
>>> inst.func()
old class

 

#重新定义类
>>> class MyClass():
 def func(self):
  print("new class")

  

#新类的实例
>>> instNew=MyClass()

 

#分别调用两个实例的func方法
>>> instNew.func()
new class
>>> inst.func()
old class
>>> type(inst)
<class '__main__.MyClass'>
>>> type(instNew)
<class '__main__.MyClass'>

#通过id查看两个类
>>> id(type(inst))
32627560
>>> id(type(instNew))
28065824

#通过id查看浮点数类
>>> id(float)
505297976
>>> id(type(0.2))
505297976
>>>

注意上面的实验很有意思。就是两个实例,都是类MyClass的实例,但是却是不同类的实例,但是类的名字一样。就是在第二次定义MyClass类时,并没有改变inst的类定义。也就是说,现在有两个同名的类。

通过type(),我们会发现两个类名完全一样。这个就很有意思了,容易让人造成困扰,怎么我同样的两个MyClass的实例,调用同样的方法(func),却产生了完全不同的输出。

要理解这点,就得深入的理解python的动态性。

1、在第一次定义MyClass的时候,同时定义了两个东西,一个是名字(符号名),二个是内存结构。名字就是:MyClass,它绑定到这个内存结构。而内存结构,就是一个新的类型(不是类)实例(Type的实例)。

2、inst=MyClass() 语句生成一个 MyClass的实例。这个实例有个指针,指向它的“类型内存结构”,也就是MyClass的内存结构。

3、第二次定义MyClass的时候,其实是只定义了一个内存结构(新类),同时将"MyClass"(名字)绑定到新的内存结构。

4、instNew=MyClass()的时候,通过查找MyClass绑定的内存结构,实例化新类。因此instNew指向的“类型内存结构”,是新类的定义。

因此,inst和instNew其实是不同的类实例。只是因为两个类定义的名字一样,而两个名字是存在type实例(类型实例)的:__name__属性中的,type(*):调用只是返回这个__name__属性的字符串。

 

而第一个类型定义,并不会被释放,为什么呢?因为__main__ ===>  inst ===> MyClass(旧)。

如果我们改变变量inst,那么就失去了对旧类的引用,旧类也就变成了垃圾,可以回收了。

原创粉丝点击