自学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
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
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
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')
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
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__'
'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
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
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:
@staticmethoddef 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
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'>
(<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>)
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
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
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
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
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
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.数据私有化