自学python系列12:python的面对对象

1.1.新式类跟经典类的学习,类与实例

新式类:
class A(bases):
     pass
bases可以是一个或多个用于继承的父类。
经典类:
class B:
     pass
object是“所有类之母”,如果你的类没有继承任何其他父类。那么object将为默认的父类。若你没有直接或间接地子类化一个对象,那么他为经典类。
     
类的实例化(没有使用new关键字哦)
a=A()
 
1.2.方法
在python中调用一个方法的途径是这样的:1.定义类(和方法)2.创建一个实例3.用这个示例调用方法,例如:
>>> class Example1(object):
      def prinfFoo(self):
          print 1

         
>>> test1=Example1()
>>> test1.prinfFoo()
1
 
你应该注意到了self参数,这个参数代表了实例对象本身。当用实例调用方法时,由解释器悄悄传递给方法。
在其他语言中,self相对于“this”
 
一种特殊的方法__init__():类似于类构造器。
1.3.创建一个类(类定义)
class Example2():
     def __init__(self,nm,ph):
          self.name=nm
          self.phone=ph
          print'your name is',self.name
     def updatePhone(self,newph):
          self.phone=newph
          print 'new phone',self.phone
__init__在实例化的时候被调用。你可以认为实例化是对__init__()的一种隐式调用。
 
1.4创建实例(实例化)以及访问实例属性,方法调用
>>> john=Example2('a','1')
your name is a
>>> jane=Example2('b','2')
your name is b
>>> john
<__main__.Example2 instance at 0x02734D50>
>>> john.name
'a'
>>> john.updatePhone('123')
new phone 123
 
1.5创建子类以及使用子类
class Example3(Example2):
     def __init__(self,nm,ph,id,em):
          Example2.__init__(self,nm,ph)
          self.empid=id
          self.empem=em

         
>>> john=Example3('c','321',42,'79523822@qq.com')
your name is c
>>> john.updatePhone('1')
 
 
类名通常由大写字母打头。类的属性中数据值像“name”,“phone”,“email”,行为如“updatePhone”。这是常说的“混合记法”和“骆驼记法”
 
2类属性
2.1类的数据属性
     数据属性仅仅是所定义的类的变量,它们可以像任何其他变量一样在类创建后被使用,要么由类中的方法类更新,要么在主程序的其他地方更新
     这种就是静态变量。java或者c++,这个变量声明前加上static关键字
>>> class C(object):
     foo=100

    
>>> print C.foo
100
>>> C.foo=C.foo+1
>>> C.foo
101
2.2查看类的属性
     两种方法查看类的属性,dir()内建函数,类的字典属性__dict__
>>> class Myclass(object):
     'Myclass class definition' #类定义
     myVersion='1'#静态数据
     def showMyVersion(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', 'showMyVersion']
>>> Myclass.__dict__
dict_proxy({'__module__': '__main__', 'showMyVersion': <function showMyVersion at 0x02AA43F0>, '__dict__': <attribute '__dict__' of 'Myclass' objects>, 'myVersion': '1', '__weakref__': <attribute '__weakref__' of 'Myclass' objects>, '__doc__': 'Myclass class definition'})
>>> Myclass.__doc__
'Myclass class definition'
>>> Myclass.__module__
'__main__'
 
     从上面可以看到,dir()返回的仅仅是对象的属性的列表,而__dir__返回的是一个字典
 
2.3.实例
1.__init__()构造器
2.__new__()构造器
3.__del__()解构器
>>> 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()
>>> a.howMany()
2
>>> b.howMany()
2
>>> del a
>>>b.howMany()
>>>1
 
3.3静态方法和类方法。
     通常的方法需要一个实例(self)作为第一个参数,并且对于方法调用来说,self是自动传递给这个方法的。而对应类方法而言,需要类而不是实例作为第一个参数,它是由解释器传给方法。很多人使用cls作为变量名字
     3.3.1staticmethod()和classmethod()函数
>>> class TestA:
     def foo():
          print'a'
     foo=staticmethod(foo)

    
>>> class TestB:
     def foo(cls):
          print'b'
     foo=classmethod(foo)

    
>>> b=TestB()
>>> b.foo()
b

    
>>> a=TestA()
>>> a.foo
<function foo at 0x0000000002849B38>
>>> a.foo()
a
 
这里注意一点。staticmethod的函数括号里不用写参数;而classmethod()需要定义函数时括号里加cls
 
     3.3.2使用函数修饰符
     >>> class TestA:
     @staticmethod
     def foo():
          print'a'

         
>>> a=TestA()
>>> a.foo()
a
>>> class TestB:
     @classmethod
     def foo(cls):
          print'b'

         
>>> b=TestB()
>>> b.foo()
b
 
这样代码就简洁多拉
 
4.有关子类和派生
>>> class A(object): #父类
     def foo(self):
          print'a'

         
>>> class B(A):#子类
     def b(self):
          print'b'

         
>>> a=A()
>>> a.foo()
a
>>> b=B()
>>> b.foo() #子类调用父类方法
a
 
>>> B.__bases__#类名
(<class '__main__.A'>,)
>>> b.__class__#子类的父类
<class '__main__.B'>
 
4.1__bases__类属性
     查看父类专用
>>> class A():
     pass

>>> class B(A):
     pass

>>> class C(A,B):
     pass

>>> A.__bases__
()
>>> B.__bases__
(<class __main__.A at 0x0000000002843F48>,)
>>> C.__bases__
(<class __main__.A at 0x0000000002843F48>, <class __main__.B at 0x0000000002855048>)
 
4.2通过继承覆盖方法
>>> class A(object):
     def foo(self):
          print'a'

         
>>> a=A()
>>> a.foo()
a
>>> class B(A):
     def foo(self):
          print'b'

         
>>> b=B()
>>> b.foo()
b
这样子类方法就把父类中定义的方法给覆盖了
     
     那么,现在问题来了,我不想把父类同名称的方法给覆盖掉该怎么办?使用super()内建函数
>>> class C(A):
     def foo(self):
          super(C,self).foo()
          print'c'

         
>>> c=C()
>>> c.foo()
a
c
super()不但能找到基类方法,还为我们传递self
 
接下来我们看看super()内建函数在__init__中的应用
>>> class A(object):
     def __init__(self):
          print'A'

         
>>> class B(A):
     def __init__(self):
          print'b'

         
>>>
>>> b=B()
b
>>> class C(A):
     def __init__(self):
          super(C,self).__init__()
          print 'c'

         
>>> c=C()
A
c
4.3从标准类型中派生
     4.3.1不可变类型
     一个浮点型的子类例子
     我们覆盖了__new__()特殊方法来定制我们的对象,使之和标准python浮点型有一点区别:
使用round()内建函数对原浮点型进行舍入操作,然后实例化我们的float:A。
     注意,所有的__new__()方法都是类方法,我们要显示得传入类,cls
>>> class A(float):
     def __new__(cls,val):
          return super(A,cls).__new__(cls,round(val,2))

    
>>> A(1.5666)
1.57
     4.3.2可变类型
     class B(dict):

     def keys(self):
          return sorted(super(B,self).keys)

4.4多继承
     python支持多继承
     新式类有个__mro__属性,告诉你子类的cha'z
 
5.类,实例以及其他对象的内建函数
5.1issubclass()
     判断一个类是另外一个类的子类或者子孙类
>>> class A(object):
     def __init__(self):
          print'A'

          
>>> class B(A):
     def __init__(self):
          print'b'

          
>>> issubclass(A,B)
False
>>> issubclass(B,A)
True
5.2isintance()
     判定一个对象是否是另一个给定类的实例
     >>> isinstance(a,A)

True

     注意一点,第二个参数也应该是类;不然会有typeerror
6.特殊方法的定制类
 
7.数据私有化
     
 
 
     
posted @ 2014-11-26 16:02  Mr.Dantes  阅读(205)  评论(0编辑  收藏  举报