13章面向对象
13.4.1 类的数据属性
数据属性仅仅是所定义的类的变量,这种属性要么是由类的方法来更新,要么是主程序其他地方更新,这种属性类似Java中静态变量。这种数据是与所属类对象绑定不依赖于任何类实例。类属性仅于类相关,和实例属性不同,类属性和实例无关。
>>> class C(object): foo = 100 >>> print C.foo 100 >>> C.foo = C.foo+1 >>> C.foo 101 >>>
13.4.2
1.方法
类定义的一部分函数(方法即是类属性)
2.绑定
13.4.3
查看一个类具有哪些属性dir(), __dict__.
13.5 实例
初始化:函数操作符
>>> class MyClass(object): pass >>> myClass = MyClass() #实例化 >>>
__init__():“构造器”方法。一旦对象创建了, python会检查是否实现了__init__()方法。默认如果没有定义(或覆盖)该方法,对实例不会施加任何操作,即任何所需特定操作,都需要程序员实现__init__()。如没有实现该方法则返回它的对象。
__new__(): "构造器方法", 比__init__更像构造器。因为它会返回一个合法实例。该方法是在新式类中新出现的方法,它作用在构造方法建造实例之前
>>> class T(object): def __init__(self, *args, **kwargs): print 2 def __new__(cls, *args, **kwargs): print 1 return object.__new__(T,*args, **kwargs) >>> t = T() 1 2 >>>
__del__():“解构器”方法。解构器是在类实例所有的引用被清除掉了才被调用的。
13.6实例属性
设置实例的属性可以在实例创建后任意时间进行,也可以在能够访问实例的代码中进行,主要是在__init__()中。通过内建dir()可以打印所有实例属性
注:python可以在“运行时”创建实例,允许对象熟悉动态创建。
13.7 绑定和方法的调用
self变量用于在实例方法中引用方法所绑定的实例。因为方法的实例在任何方法中总是作为第一个参数传递,self被选中用来代表实例。(类似java 的this)
调用绑定方法:通过实例调用
调用非绑定方法:最形象的类似子类继承父类,需要调用父类的构造器.
>>> class A(object): pass >>> class B(A): def __init__(self): A.__init__(self)
13.8 静态方法和类方法
通常的方法需要一个self作为第一个参数,并且对于绑定方法的调用来说,self是自动传递给这个方法的,而对于类方法来说,需要类不是实例作为第一个参数,它由解释器传给方法。类不需要特别的命名,类似self,不过大多数使用cls
>>> class TestStaticMethod(object): @staticmethod def foo(): print 'Test Static method' >>> class TestClassMethod(object): @classmethod def foo(cls): print "Test Class method" >>> static = TestStaticMethod() >>> static.foo() Test Static method >>> TestStaticMethod.foo() Test Static method >>> Class = TestClassMethod() >>> Class.foo() Test Class method >>> TestClassMethod.foo() Test Class method
13.11 继承
>>> class P(object): def foo(self): print 'Hi, i am P-foo()' >>> p = P() >>> p.foo() Hi, i am P-foo() >>> class C(P): def foo(self): print 'Hi, i am C-foo()' >>> c = C() >>> c.foo() Hi, i am C-foo()
C类继承了P的foo()方法, 但因为C定义了自己的foo()方法,所以P中的foo()方法被覆盖。
如果想调用父类的foo()方法,需要调用一个未绑定的基类方法,明确给予子类的实例。
>>> class P(object): def foo(self): print 'Hi, i am P-foo()' >>> class C(P): def foo(self): super(C, self).foo() print 'Hi, i am C-foo()' >>> c = C() >>> c.foo() Hi, i am P-foo() Hi, i am C-foo() >>>
和java不同的是,当从一个带构造器__init__()的类继承,如果不去覆盖__init__(),它将会被继承并自动调用,但如果子类覆盖__init__(),子类被实例化时基类的__init__()就不会被调用。如果想调用父类__init__(),就需要显示使用子类的实例去调用基类方法。
>>> class P(object): def __init__(self): print 'calling p is constructor' >>> class C(P): def __init__(self): print 'calling C is constructor' >>> c = C() calling C is constructor >>> class C(P): def __init__(self): P.__init__(self) print 'calling C is constructor' >>> c = C() calling p is constructor calling C is constructor
13.12 类的一些内建函数
issubclass()判断一个类实另一个的子类, isinstance()判断一个对象是否是另一个给定类的实例
hasattr()判断一个对象是否有一个特定属性,一般用作访问属性前作检查
getattr(), setattr() 相应地取和赋值给对象的属性
delattr(),相应的从一个对象中删除属性
>>> class myClass(object): def __init__(self): self.foo = 100 >>> myInst = myClass() >>> hasattr(myInst, 'foo') True >>> getattr(myInst, 'foo') 100 >>> setattr(myInst, 'bar', 200) >>> getattr(myInst, 'bar') 200 >>> dir(myInst) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo']
13.14 私有化
__双下划线:有双下划线的属性在运行时被“混淆”,所以直接访问是不允许的,内部是在名字前面加上下划线和类名,可以防止子类和父类同名的冲突情况即子类也不能访问。类似java的private
_单下划线:在属性前加单下划线可防止模块的属性用“from model import *”来加载.子类可访问,类似java protect
__xxx___ 定义的是特列方法。像__init__之类的