Python中特殊的类属性

对任何类C    显示了类C的所有特殊属性:




C.__name__ 类C的名字(字符串)
C.__doc__ 类C的文档字符串
C.__bases__ 类C的所有父类构成的元组
C.__dict__ 类C的属性
C.__module__ 类C定义所在的模块(1.5 版本新增)
C.__class__ 实例C对应的类(仅新式类中)
__init__() “构造器”方法
__new__() “构造器”方法
__del__() "解构器"方法




__name__是给定类的字符名字。它适用于那种只需要字符串(类对象的名字),而非类对象本身
的情况。 甚至一些内建的类型也有这个属性, 我们将会用到其中之一来展示__name__字符串的益处。


__doc__是类的文档字符串,与函数及模块的文档字符串相似,必须紧随头行(header line)
后的字符串。文档字符串不能被派生类继承,也就是说派生类必须含有它们自己的文档字符串。


__bases__用来处理继承,它包含了一个由所有父类组成的元组。


__dict__属性包含一个字典,由类的数据属性组成。访问一个类属性的时候,Python 解
释器将会搜索字典以得到需要的属性。 如果在__dict__中没有找到, 将会在基类的字典中进行搜索,
采用“深度优先搜索”顺序。基类集的搜索是按顺序的, 从左到右,按其在类定义时,定义父类参
数时的顺序。对类的修改会仅影响到此类的字典;基类的__dict__属性不会被改动的。


Python 支持模块间的类继承。为更清晰地对类进行描述,__module__,
这样类名就完全由模块名所限定。看一下下面的例子:
>>> class C(object):
... pass
...
>>> C
<class __main__.C at 0x53f90>
>>> C.__module__
'__main__'


类 C 的全名是“__main__.C”,比如,source_module.class_name。如果类 C 位于一个导入的
模块中,如 mymod,像下面的:
>>> from mymod import C
>>> C
<class mymod.C at 0x53ea0>
>>> C.__module__
'mymod'
没有特殊属性__module__, 很难简单定位类的位置,因为类没有使用它们的
全名。


由于类型和类的统一性,当访问任何类的__class__属性时,你将发现它就是一个类型对
象的实例。换句话说,一个类已是一种类型了。因为经典类并不认同这种等价性(一个经典类是一
个类对象,一个类型是一个类型对象),对这些对象来说,这个属性并未定义。


__init__():当类被调用,实例化的第一步是创建实例对象。一旦对象创建了, Python 检查是否实现了
__init__()方法。默认情况下,如果没有定义(或覆盖)特殊方法__init__(),对实例不会施加任
何特别的操作.任何所需的特定操作,都需要程序员实现__init__(),覆盖它的默认行为。如果
__init__()没有实现,则返回它的对象,实例化过程完毕 然而,如果__init__()已经被实现,那么它将被调用,实例对象作为第一个参数(self)被传递
进去,像标准方法调用一样。调用类时,传进的任何参数都交给了__init__()。实际中,你可以想
像成这样:把创建实例的调用当成是对构造器的调用。 总之,(a)你没有通过调用 new 来创建实例,你也没有定义一个构造器。是 Python 为你创建了
对象; (b) __init__(),是在解释器为你创建一个实例后调用的第一个方法,在你开始使用它之前,这一步可以让你做些准备工作。 


与__init__()相比, __new__()方法更像一个真正的构造器。类型和类在版本 2.2 就统一了,
Python 用户可以对内建类型进行派生,因此,需要一种途径来实例化不可变对象,比如,派生字符
串,数字,等等。
在这种情况下,解释器则调用类的__new__()方法,一个静态方法,并且传入的参数是在类实例
化操作时生成的。__new__()会调用父类的__new__()来创建对象(向上代理)。
为何我们认为__new__()比__init__()更像构造器呢?这是因为__new__()必须返回一个合法
的实例,这样解释器在调用__init__()时,就可以把这个实例作为 self 传给它。调用父类的__new__()
来创建对象,正像其它语言中使用 new 关键字一样。


同样,有一个相应的特殊解构器(destructor)方法名为__del__()。然而,由于 Python 具有
垃圾对象回收机制(靠引用计数),这个函数要直到该实例对象所有的引用都被清除掉后才会执行。
Python 中的解构器是在实例释放前提供特殊处理功能的方法,它们通常没有被实现,因为实例很少
被显式释放
在下面的例子中,我们分别创建(并覆盖)__init__()和__del__()构造及解构函数,然后,初
始化类并给同样的对象分配很多别名。id()内建函数可用来确定引用同一对象的三个别名。最后一
步是使用 del 语句清除所有的别名,显示何时,调用了多少次解构器。
class C(P): # class declaration 类声明
def __init__(self): # "constructor" 构造器
print 'initialized'
def __del__(self): # "destructor" 解构器
P.__del__(self) # call parent destructor print 'deleted' 调用父类解构器来打印
'deleted'
>>> c1 = C() # instantiation initialized 实例初始化
>>> c2 = c1 # create additional alias 创建另外一个别名
>>> c3 = c1 # create a third alias 创建第三个别名
>>> id(c1), id(c2), id(c3) # all refer to same object 同一对象所有引用
(11938912, 11938912, 11938912)
>>> del c1 # remove one reference 清除一个引用
>>> del c2 # remove another reference 清除另一个引用
>>> del c3 # remove final reference deleted # destructor finally invoked 解构器最
后调用
注意,在上面的例子中,解构器是在类 C 实例所有的引用都被清除掉后,才被调用的,比如,
当引用计数已减少到 0。如果你预期你的__del__()方法会被调用, 却实际上没有被调用, 这意味着,
你的实例对象由于某些原因,其引用计数不为 0,这可能有别的对它的引用,而你并不知道这些让
你的对象还活着的引用所在。
另外,要注意,解构器只能被调用一次,一旦引用计数为 0,则对象就被清除了。这非常合理,
因为系统中任何对象都只被分配及解构一次。
总结:
 不要忘记首先调用父类的__del__()。
 调用 del x 不表示调用了 x.__del__() -----前面也看到,它仅仅是减少 x 的引用计数。
 如果你有一个循环引用或其它的原因,让一个实例的引用逗留不去, 该对象的__del__()可
能永远不会被执行。
 __del__()未捕获的异常会被忽略掉(因为一些在__del__()用到的变量或许已经被删除了)。
不要在__del__()中干与实例没任何关系的事情。
 除非你知道你正在干什么,否则不要去实现__del__()。
 如果你定义了__del__,并且实例是某个循环的一部分,垃圾回收器将不会终止这个循环—
—你需要自已显式调用 del

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python,类的属性是指与该类相关联的变量或值。类的属性可以是类属性和实例属性两种类型。 1. 类属性属性是指定义在类,而不是在类的实例属性。类属性可以被所有该类的实例共享,并且可以通过类名和实例对象来访问。类属性通常用于存储该类的一些公共信息或默认值。类属性可以在类定义,也可以在类外通过类名来定义。 下面是一个简单的示例代码,定义了一个类属性: ```python class MyClass: class_attr = 0 print(MyClass.class_attr) # 0 ``` 2. 实例属性 实例属性是指定义在类的实例属性。每个类的实例都有自己的实例属性,它们在不同的实例可以有不同的值。实例属性通常用于存储与该实例相关的信息。 实例属性可以在类的方法通过self关键字来访问和修改。也可以通过实例对象来访问和修改。 下面是一个示例代码,定义了一个实例属性: ```python class MyClass: def __init__(self, inst_attr): self.inst_attr = inst_attr my_obj = MyClass(1) print(my_obj.inst_attr) # 1 ``` 在这个示例代码,我们定义了一个实例属性inst_attr,并在类的初始化方法__init__进行了初始化。然后我们创建了一个类的实例my_obj,并访问了该实例的实例属性inst_attr。 总之,类的属性是指与该类相关联的变量或值。类的属性可以是类属性和实例属性两种类型,它们在Python都具有重要的作用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值