Python是面向对象编程语言,正如Java、C++一般,C属于面向过程语言。
作为面向对象来说类的存在是很必要的。
1.创建基本类类型
类的基本创建格式
>>> class classname:
#定义方法和属性
pass
>>>
创建实例
>>> class Demo:
pass
>>> D = Demo() #需要加上括号,调用方法时也用该加上括号
2.可以在类里面用def定义方法(Methods)和数据,这里在类里叫方法而不是函数,方法的第一个参数都是self,在调用的时候不输入,程序会自动将第一个参数绑定到所属的实例上。
>>> class Demo:
def Helloworld(self,argus):
a = 'Hello'
print(a + argus)
>>> D = Demo() #需要加上()
>>> D.Helloworld('world')<span style="white-space:pre"> </span>#只提供一个参数
Helloworld
>>> class Demo:
def a():
print('a')
>>> Demo.a() #类直接调用没有出现异常
a
>>> D = Demo() #实例调用时出现异常
>>> D.a()
Traceback (most recent call last):
File "<pyshell#226>", line 1, in <module>
D.a()
TypeError: a() takes 0 positional arguments but 1 was given
注意类里面的数据与方法里面的数据不是互通的
>>> class Demo:
a = 'World'
def Helloworld(self,argus):
a = 'Hello'
print(a)
>>> D = Demo()
>>> D.a #a是类里面的
'World'
>>> D.Helloworld('a')
Hello #输出的是方法里面的
方法试图调用类里面的数据
>>> class Demo:
a = 'World'
def Helloworld(self,argus):
print(a)
>>> D = Demo()
>>> D.a
'World'
>>> D.Helloworld('a')
Traceback (most recent call last):
File "<pyshell#57>", line 1, in <module>
D.Helloworld('a')
File "<pyshell#54>", line 4, in Helloworld
print(a)
NameError: name 'a' is not defined<span style="white-space:pre"> #出现异常,a没有被定义
类试图调用方法里面的数据
>>> class Demo:
def Helloworld(self,argus):
a = 'World'
print(a)
>>> D = Demo()
>>> D.a
Traceback (most recent call last):
File "<pyshell#61>", line 1, in <module>
D.a
AttributeError: 'Demo' object has no attribute 'a' #里面没有a
>>> class Demo:
a = 'World'
def dis(self,a):
print(a)
>>> D = Demo()
>>> D.dis()
Traceback (most recent call last):
File "<pyshell#108>", line 1, in <module>
D.dis()
TypeError: dis() missing 1 required positional argument: 'a'
那么怎么在方法中输出类中的数据呢,可以用self,在创建实例的时候self,自动绑定在所创建的实例身上,然后在方法中使用self.a (a为类中的数据),就可以调用了
但是只能够在实例上使用
>>> class Demo:
a = 'Hello world'
def fun(self):
print(self.a)
>>> D = Demo()
>>> D.fun() #实例可以调用
Hello world
>>> Demo.fun() #类不可以调用,因为self没有绑定实例
Traceback (most recent call last):
File "<pyshell#268>", line 1, in <module>
Demo.fun()
TypeError: fun() missing 1 required positional argument: 'self'
3.访问类中的数据
两种访问方式,通过类名字来访问和通过实例来访问
>>> class Demo:
a = 1
>>> Demo.a #类名字
1
>>> D = Demo() #实例
>>> D.a
1
实例的数据的改变不能影响到类中的数据
>>> class Demo:
a = 1
>>> D = Demo()
>>> D.a
1
>>> D.a = 2
>>> D.a
2
>>> Demo.a
1
类中的数据的改变可以影响到实例
>>> class Demo:
a = 1
>>> D = Demo()
>>> D.a
1
>>> Demo.a
1
>>> Demo.a = 2
>>> Demo.a
2
>>> D.a
2
>>> Demo.a = 3
>>> D.a
3
但是实例中的数据一旦赋值后,类中的改变不能影响到实例中的数据
>>> class Demo:
a = 1
>>> D = Demo()
>>> D.a
1
>>> Demo.a
1
>>> D.a = 99 #对实例中的a赋值99
>>> Demo.a = 100 #改变类中的a为100
>>> Demo.a #类中的值改变
100
>>> D.a #实例中的值不变
99
>>> del D.a #可以用的del删除D的a数据
>>> D.a #这时候再输出实例中的a就是类中的a了
100
4.类的特殊属性(属性貌似就是上个程序中的a,例如D.a,则a也叫作属性,但本人习惯称为数据,所以出现数据的时候,应该是属性)
C.__name__(类C的名字)
>>> class Demo:
pass
>>> Demo.__name__
'Demo'
>>> class A:
pass
>>> class B(A):
pass
>>> B.__bases__
(<class '__main__.A'>,) #父类A
>>> A.__bases__
(<class 'object'>,) #默认object
>>>
C.__module__(类C定义所在的模块)
>>> class Demo:
pass
>>> Demo.__module__
'__main__'
C.__class__(实例C对应的类,这里C的实例)
>>> class Demo:
pass
>>> D = Demo()
>>> D.__class__
<class '__main__.Demo'>
>>>
5.__init__()、__del__()
__init__( ) 构造器,这是一个特殊的方法,类似于C++中的构造函数,就是用来对初始化实例的,创建实例是先检查是否有这个方法,有的话就调用方法来实例进行初始化。
>>> class Demo:
def __init__(self):
print('AAA')
>>> D = Demo() #创建实例时直接自动调用
AAA
>>> class Demo:
count = 0;
def __init__(self):
Demo.count += 1 #每次调用时候+1,注意是Demo,不是self,因为实例的改变不会改变类的。
print(self.count)
>>> D1 = Demo()
1
>>> D2 = Demo()
2
>>> D3 = Demo()
3
__del__( ) 解构器,与__init__对应,类似于C++中的析构函数,在实例被清除时调用的。
>>> class Demo:
count = 0;
def __init__(self):
Demo.count += 1
print(self.count)
def __del__(self):
Demo.count -= 1
print(self.count)
>>> D1 = Demo()
1
>>> D2 = Demo()
2
>>> D3 = Demo()
3
>>> del D1
2
>>> del D2
1
>>> del D3
0
6.如其他面向对象语言一样,类具有封装、继承、多态(对于python类的多态不太了解)的特点
封装
Python中类的数据默认都是公有的、如果想变成私有的需要在前面加上两个下划线
默认情况是公有的可以直接调用
>>> class Demo():
a = 'Hello world'
>>> D = Demo()
>>> D.a
'Hello world'
加入下划线变成私有的
>>> class Demo():
__a = 'Hello world'
>>> D = Demo()
>>> D.a #不可访问,写成D.__a也无法调用
Traceback (most recent call last):
File "<pyshell#78>", line 1, in <module>
D.a
AttributeError: 'Demo' object has no attribute 'a'
可以这样访问
所以说python 的封装并不能完完全实现封装
>>> D._Demo__a #实例._类名__数据名字
'Hello world'
方法也一样类似
>>> class Demo():
def __test(self):<span style="white-space:pre"> </span>#定义私有方法
print('hello')
def dis(self):<span style="white-space:pre"> </span>#绑定实例后,输出私有方法
self.__test()
>>> D = Demo()
>>> D.dis
<bound method Demo.dis of <__main__.Demo object at 0x0000000003128BA8>>
>>> D.dis()<span style="white-space:pre"> </span>#需要加上括号
hello
>>> D.test()<span style="white-space:pre"> </span>#试图调用私有方法,失败
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
D.test()
AttributeError: 'Demo' object has no attribute 'test'
>>> D.__test()<span style="white-space:pre"> </span>#加上__也不行
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
D.__test()
AttributeError: 'Demo' object has no attribute '__test'
</pre><p></p><p>继承</p><p>单继承</p><p></p><pre name="code" class="python">>>> class A:
pass
>>> class B(A): #B继承A
pass
多继承
>>> class A:
pass
>>> class B:
pass
>>> class D(A,B):
pass
>>> A.__bases__
(<class 'object'>,)
>>> B.__bases__
(<class 'object'>,)
>>> D.__bases__
(<class '__main__.A'>, <class '__main__.B'>)
可以用__bases__属性查看父类,也可以用issubclass查看子类(issubclass(1,2) 查看1是不是2的子类)
>>> class A:
def a(self):
print('A')
>>> class B(A):
def b(self):
print('B')
>>> A.__bases__
(<class 'object'>,)
>>> B.__bases__
(<class '__main__.A'>,)
>>> issubclass(A,B) #A不是B的子类
False
>>> issubclass(B,A) #B是A的子类
True
继承时,如果子类中有跟父类相同的方法名字,则会覆盖父类的方法,如果没有则会继承下来,可以用子类的实例输出父类中的方法,如果是多重继承的话,会一次从左到到的继承顺序,来查找该方法。
>>> class A:
def fun(self):
print('A')
>>> class B(A):
def fun(self):
print('B')
>>> class C(A):
def fun(self):
print('C')
>>> class D(B,C):
def fun(self):
print('D')
>>> a = A()
>>> b = B()
>>> c = C()
>>> d = D()
>>> a.fun()
A
>>> b.fun()
B
>>> c.fun()
C
>>> d.fun() #如果子类中有fun()方法就直接输出子类中的
D
>>> class D(B,C): #重新定义类D,使类中不存在fun()方法,继承顺序为B、C
pass
>>> d = D()
>>> d.fun() #输出实例d中的fun()方法,这时会调用类B的fun
B
>>> class D(C,B): #调换B、C的位置,C在前面
pass
>>> d = D()
>>> d.fun() #输出的是C的fun
C