Python学习之路——类
类:
类是将抽象的实物进行的划分。 在现实世界中如果我们将: 人类包含:男人、女人、孩子、老人等
动物类包含:小猫、小狗、小兔子等 在代码世界中我也可以分类,例如将相同功能的代码放到一起,这就是分类。
对像:
对像是类的实体,你、我、他、小强、小明都可以是一个实体对像。
方法:
每个人的动作可以看作是方法,例如说吃饭、洗脸、说话。
继承:
不论是老年人、中年人还是青年人,这三个年龄段的人最后都归属人这个大类,也就是继承人的特点。
封装:
每个人头脑里记忆的东西只有自己可以使用,另一个人无法使用。这对于另一个人来说就是封装。
多态:
有人吃饭快,有人吃饭慢,有人吃的多,有人吃的少,这就是多态。
在代码中:
类就是一个模板,模板里可以包含多个函数,函数里实现一些功能 对象则是根据模板创建的实例,通过实例对象可以执行类中的函数
创建类:
class people(): """A simple example class""" def man(self): print('这是一个男人。') def woman(self): print('这是一个女人。') x = people() #实例化类 x.man() #执行函数 x.woman() #执行函数 以上实例输出结果: 这是一个男人。 这是一个女人。
一、函数封装:
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
所以,在使用面向对象的封装特性时,需要:
- 将内容封装到某处
- 从某处调用被封装的内容
在内存里就是:
在类中调用默认函数:
class people(): def __init__(self,name,age): #默认函数 self.test = name self.test1 = age #注self.后面的变量名可以不定要去形参相同,例如第二个变量。 def statu(self): print('name: %s,ege:%s' %(self.test,self.test1)) #在其他函数调用要加self x = people('earl','20') #将earl、20封装到x的中. x.statu() 以上实例输出结果: name: earl,ege:20
二、继承:
继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。
1、继承一个:
class A(object): n = 'A' def f2(self): print("f2 from A") class B(A): n = 'B' def f1(self): print("from B") 以上实例输出结果: from B f2 from A
2、继承多个:
class A(object): n = 'A' def f2(self): print("f2 from A") class B(A): n = 'B' def f1(self): print("from B") class C(A): n = 'C' def f2(self): print("f2 from C") class D(B,C): '''Test class''' # def __del__(self): # print("deleteing the ...") d = D() d.f1() d.f2() 以上实例输出结果: from B f2 from C
多继承优先级别:
class A: n = 'A' def f2(self): print("f2 from A") class B(A): n = 'B' def f1(self): print("from B") # def f2(self): # print("f2 from B") class C(A): n = 'C' def f2(self): print("f2 from C") class D(B,C): '''Test class''' d = D() d.f1() d.f2()
python2.x版本中:
经典类:首先去D类中查找,如果D类中没有,则继续去B类中找,如果B类中么有,则继续去A类中找,如果A类中么有,则继续去C类中找,如果还是未找到,则报错
新式类:首先去D类中查找,如果D类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去A类中找,如果还是未找到,则报错
python3.x版本中:
经典类:首先去D类中查找,如果D类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去A类中找,如果还是未找到,则报错
新式类:首先去D类中查找,如果D类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去A类中找,如果还是未找到,则报错
注意:在上述查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找了
三、多态:
Python不支持多态,在开发中也用不到多态。
父类调用子类:
class Animal: def __init__(self, name): self.name = name def talk(self): raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal): def talk(self): return 'Meow!' class Dog(Animal): def talk(self): return 'Woof! Woof!' def animal_talk(obj): print(obj.talk()) c = Cat("jack") d = Dog("tom") animal_talk(c) animal_talk(d) 以上实例输出结果: Meow! Woof! Woof!
四、公有属性私有属性:
私有属性就是在变量前面加两个下划线。
class X: def __init__(self): self.name = '公有字段' self.__foo = "私有字段"
私有成员只能在类内部使用
class X: __name = "私有字段" foo = '公有字段' def func(self): print(X.__name) class D(X): def show(self): print(X.__name) Y = X() Y.func() # 类内部可以访问正常 Z = D() Z.show() #外部类访问报错
五、类的特殊成员:
1. __doc__
表示类的注释信息
class Foo: """ 此类备注信息 """ def func(self): pass print(Foo.__doc__) 以上实例输出结果: 此类备注信息
2. __module__ 和 __class__
__module__ 表示当前操作的对象在那个模块
__class__ 表示当前操作的对象的类是什么
class X: def __init__(self): self.name = 'earl'
import aa obj = aa.X() print(obj.__module__)# 输出 aa,即:输出模块 print(obj.__class__) # 输出 aa.X,即:输出类 以上实例输出结果: aa <class 'aa.X'>
3、__init__初始函数:
class people(): def __init__(self,name,age): #默认函数 self.test = name self.test1 = age #注self.后面的变量名可以不定要去形参相同,例如第二个变量。 x = people('earl','20') #将earl、20封装到x的中. #调用: print(x.test) #调用X对像中的test属性 print(x.test1) #调用X对像中的test1属性
4、__dict__:
以字典形式显示:
class Province: country = 'China' def __init__(self, name, count): self.name = name self.count = count def func(self, *args, **kwargs): print('func') # 获取类的成员,即:静态字段、方法、 print(Province.__dict__) # 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None} obj1 = Province('HeBei',10000) print(obj1.__dict__) # 获取 对象obj1 的成员 # 输出:{'count': 10000, 'name': 'HeBei'} obj2 = Province('HeNan', 3888) print(obj2.__dict__) # 获取 对象obj1 的成员 # 输出:{'count': 3888, 'name': 'HeNan'}
六、反射:
python中的反射是使程序能够通过参数调用类中的成员。
反射由四个内置函数提供:
hasattr #判断是某个成员是不存在。
getattr #获取成员
setattr #添加成员到实例里(注:此函数是将函数添加到实例化的对像里,而不是添加到类里。)
delattr #删除成员(注:此函数是参数类里成员。)
1、hasattr与getattr
hasattr与getattr要配合使用:
import sys class WebServer(object): def __init__(self,host,port): self.host = host self.port = port def start(self): print('server is starting....') def stop(self): print('serer is stopping....') def restart(self): self.stop() self.start() def test_run(name,t1): print('run.....',name,t1.host) if __name__ == '__main__': server = WebServer('localhost',123) if hasattr(server,sys.argv[1]): #判断输入sys.argv[1]在不在server这个实例里。 func = getattr(server,sys.argv[1]) #获取server.start的内存地址 func() 执行代码:python test.py start 结果如下: server is starting....
2、setattr
import sys class WebServer(object): def __init__(self,host,port): self.host = host self.port = port def start(self): print('server is starting....') def stop(self): print('serer is stopping....') def restart(self): self.stop() self.start() def test_run(name,t1): print('run.....',name,t1.host) if __name__ == '__main__': server = WebServer('localhost',123) setattr(server,'run',test_run) #将test_run函数以run的别名添加到server实例中。 server.run('earl',server) #调用函数。 运行代码:python test.py start 运行结果: run..... earl localhost
3、delattr:
import sys class WebServer(object): def __init__(self,host,port): self.host = host self.port = port def start(self): print('server is starting....') def stop(self): print('serer is stopping....') def restart(self): self.stop() self.start() def test_run(name,t1): print('run.....',name,t1.host) if __name__ == '__main__': server = WebServer('localhost',123) delattr(WebServer,'start') #删除类里的start函数。 delattr(server,'host') #删除类里的host属性。 server.host 运行代码:python test.py start 执行结果会报错: AttributeError: 'WebServer' object has no attribute 'host' 因为已经将host删除了。