Python入门篇之面向对象
面向对象设计与面向对象编程的关系 复制代码 代码如下: def functionName(args): 'function documentation string' #函数文档字符串 function_suite #函数体 class ClassName(object): 'class documentation string' #类文档字符串 class_suite #类体 二者都允许你在他们的声明中创建函数,闭包或者内部函数(即函数内的函数),还有在类中定义的方法。最大的不同在于你运行函数,而类会创建一个对象。类就像一个 Python 容器类型。尽管类是对象(在 Python 中,一切皆对象),但正被定义时,它们还不是对象的实现。 复制代码 代码如下: class ClassName(bases): 'class documentation string' #'类文档字符串' class_suite #类体 基类是一个或多个用于继承的父类的集合;类体由所有声明语句,类成员定义,数据属性和函数组成。类通常在一个模块的顶层进行定义,以便类实例能够在类所定义 有关属性的一个有趣的地方是,当你正访问一个属性时,它同时也是一个对象,拥有它自己的属性,可以访问,这导致了一个属性链,比如,myThing,subThing,subSubThing.等等 复制代码 代码如下: >>> class c(object): foo = 100 >>> print c.foo 100 >>> c.foo+=1 >>> c.foo 101 方法 复制代码 代码如下: >>> class MyClass(object): def myNoActionMethod(self): pass >>> mc = MyClass() >>> mc.myNoActionMethod() 任何像函数一样对 myNoActionMethod 自身的调用都将失败: 复制代码 代码如下: >>> myNoActionMethod() Traceback (innermost last): File "<stdin>",line 1,in ? myNoActionMethod() NameError: myNoActionMethod 甚至由类对象调用此方法也失败了。 复制代码 代码如下: >>> MyClass.myNoActionMethod() Traceback (innermost last): File "<stdin>",in ? MyClass.myNoActionMethod() TypeError: unbound method must be called with class instance 1st argument 绑定(绑定及非绑定方法) 复制代码 代码如下: >>> class myclass(object): 'myclass class definition' #类定义 myVersion = '1.1' #静态数据 def showVesion(self): #方法 print myclass.myVersion >>> dir(myclass) 运行结果: 复制代码 代码如下: ['__class__','__delattr__','__dict__','__doc__','__format__','__getattribute__','__hash__','__init__','__module__','__new__','__reduce__','__reduce_ex__','__repr__','__setattr__','__sizeof__','__str__','__subclasshook__','__weakref__','myVersion','showVesion'] 使用: 复制代码 代码如下: >>> myclass.__dict__ dict_proxy({'__module__': '__main__','showVesion': <function showVesion at 0x0134C9B0>,'__dict__': <attribute '__dict__' of 'myclass' objects>,'myVersion': '1.1','__weakref__': <attribute '__weakref__' of 'myclass' objects>,'__doc__': 'myclass class definition'}) 从上面可以看到,dir()返回的仅是对象的属性的一个名字列表,而__dict__返回的是一个字典,它的键(keys)是属性名,键值(values)是相应的属性对象的数据值。 特殊的类属性 复制代码 代码如下: >>> myclass.__name__ 'myclass' >>> myclass.__doc__ 'myclass class definition' >>> myclass.__bases__ (<type 'object'>,) >>> print myclass.__dict__ {'__module__': '__main__','__doc__': 'myclass class definition'} >>> myclass.__module__ '__main__' >>> myclass.__class__ <type 'type'> 实例 复制代码 代码如下: >>> class instCt(object): count = 0 def __init__(self): instCt.count += 1 def __del__(self): instCt.count -= 1 def howMany(self): return instCt.count >>> a = instCt() >>> b = instCt() >>> b.howMany() 2 >>> a.howMany() 2 >>> del b >>> a.howMany() 1 >>> del a >>> instCt.count 0 实例属性 复制代码 代码如下: >> class HotelRoomCalc(object): 'hotel room rate calculate' def __init__(self,rt,sales = 0.085,rm = 0.1): '''HotelRoomCalc default arguments: sales tax == 8.5% and room tax == 10%''' self.salesTax = sales self.roomTax = rm self.roomRate = rt def calcTotal(self,days = 1): 'Calculate total: default to daily rate' daily = round((self.roomRate * 14 * (1+self.roomTax + self.salesTax)),2) return float(days) * daily >>> sfo = HotelRoomCalc(299) 函数所有的灵活性,比如默认参数,也可以应用到方法中去。在实例化时,可变长度参数也是一个好的特性 复制代码 代码如下: >>> class MyClass(object): pass >>> mc = MyClass() 如果定义了构造器,它不应当返回任何对象,因为实例对象是自动在实例化调用后返回的。相应地,__init__()就不应当返回任何对象(应当为 None);否则,就可能出现冲突,因为只能返回实例。试着返回非 None 的任何其它对象都会导致 TypeError 异常: 复制代码 代码如下: >>> class MyClass: def __init__(self): print 'initialized' return 1 >>> mc = MyClass() 查看实例属性 复制代码 代码如下: >>> c = C() >>> c.foo = 'he' >>> c.bar = 'isa' >>> dir(c) ['__class__','bar','foo'] 与类相似,实例也有一个__dict__特殊属性(可以调用 vars()并传入一个实例来获取),它是实例属性构成的一个字典: 复制代码 代码如下: >>> c.__dict__ {'foo': 'he','bar': 'isa'} 特殊的实例属性 复制代码 代码如下: >>> class C(object): pass >>> c = C() >>> dir(c) ['__class__','__weakref__'] >>> c.__dict__ {} >>> c.__class__ <class '__main__.C'>>>> #可以看到,c还没有属性 >>> c.foo = 1 >>> c.bar = 'ewe' >>> '%d can of %s please' % (c.foo,c.bar) '1 can of ewe please' >>> c.__dict__ {'foo': 1,'bar': 'ewe'} 内建类型属性 复制代码 代码如下: >>> x = 2 + 2.4j >>> x.__class__ <type 'complex'> >>> dir(x) ['__abs__','__add__','__class__','__coerce__','__div__','__divmod__','__eq__','__float__','__floordiv__','__ge__','__getnewargs__','__gt__','__int__','__le__','__long__','__lt__','__mod__','__mul__','__ne__','__neg__','__nonzero__','__pos__','__pow__','__radd__','__rdiv__','__rdivmod__','__rfloordiv__','__rmod__','__rmul__','__rpow__','__rsub__','__rtruediv__','__sub__','__truediv__','conjugate','imag','real'] 试着访问__dict__会失败,因为在内建类型中,不存在这个属性 访问类属性 复制代码 代码如下: >>> class C(object): version = 2 >>> c = C() 从实例中访问类属性须谨慎 复制代码 代码如下: >>> class Foo(object): x = 1 >>> foo =Foo() 使用del后 复制代码 代码如下: >>> del foo.x >>> foo.x 1 静态成员,如其名所言,任凭整个实例(及其属性)的如何进展,它都不理不采(因此独立于实例)。同时,当一个实例在类属性被修改后才创建,那么更新的值就将生效。类属性的修改会影响到所有的实例: 复制代码 代码如下: >>> class C(object): spam = 11 >>> c1 = C() >>> c1.spam 11 >>> C.spam += 2 >>> C.spam 13 >>> c1.spam 13 >>> c2 = C() >>> c2.spam 13 >>> del c1 >>> C.spam += 3 >>> c2.spam 16 正如上面所看到的那样,使用实例属性来试着修改类属性是很危险的。原因在于实例拥有它们自已的属性集,在 Python 中没有明确的方法来指示你想要修改同名的类属性,修改类属性需要使用类名,而不是实例名。 复制代码 代码如下: >>> class TestStaticMethod: def foo(): print 'calling static method foo()' foo = staticmethod(foo) >>> class TestClassMethod: 对应的内建函数被转换成它们相应的类型,并且重新赋值给了相同的变量名。如果没有调用这两个函数,二者都会在 Python 编译器中产生错误,显示需要带 self 的常规方法声明。 复制代码 代码如下: >>> tsm = TestStaticMethod() >>> TestStaticMethod.foo() calling static method foo() >>> tsm.foo() calling static method foo() >>> tcm = TestClassMethod() >>> TestClassMethod.foo() calling class method foo() foo() is part of class: TestClassMethod >>> tcm.foo() calling class method foo() foo() is part of class: TestClassMethod 使用函数修饰符: 复制代码 代码如下: >>> class TestStaticMethod: @staticmethod def foo(): print 'calling static method foo()' >>> class TestClassMethod: (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |