Python学习笔记day7,,面向对象(类)二面向
Python学习笔记day7,,面向对象(类)二面向
面向对象(类)二
面向对象是一种编程方式,此编程方式的实现是基于对类和对象的使用类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中)对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数面向对象三大特性:封装、继承和多态类的多继承实例:
class A: def f2(self): print(‘f2 from A‘)class B(A): def f1(self): print(‘f2 from B‘)class C(A): def f1(self): print(‘f2 from C‘)class D(B,C): passd = D()d.f2()
类的成员
类的成员可以分为三大类:字段、方法和属性
一、字段
字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,
普通字段属于对象静态字段属于类class Province: # 静态字段 country = ‘中国‘ def __init__(self, name): # 普通字段 self.name = name# 直接访问普通字段obj = Province(‘河北省‘)print(obj.name)# 直接访问静态字段Province.country
由上述代码可以看出【普通字段需要通过对象来访问】【静态字段通过类访问】,在使用上可以看出普通字段和静态字段的归属是不同的。其在内容的存储方式类似如下图:
由上图可是:
静态字段在内存中只保存一份普通字段在每个对象中都要保存一份应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段
二、方法
方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;静态方法:由类调用;无默认参数;class Foo: def __init__(self, name): self.name = name def ord_func(self): """ 定义普通方法,至少有一个self参数 """ # print self.name print(‘普通方法‘) @classmethod def class_func(cls): """ 定义类方法,至少有一个cls参数 """ print(‘类方法‘) @staticmethod def static_func(): """ 定义静态方法 ,无默认参数""" print(‘静态方法‘)# 调用普通方法f = Foo()f.ord_func()# 调用类方法Foo.class_func()# 调用静态方法Foo.static_func()
相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。
不同点:方法调用者不同、调用方法时自动传入的参数不同。
三、属性
如果你已经了解Python类中的方法,那么属性就非常简单了,因为Python中的属性其实是普通方法的变种。
对于属性,有以下三个知识点:
属性的基本使用属性的两种定义方式1、属性的基本使用
# ############### 定义 ###############class Foo: def func(self): pass # 定义属性 @property def prop(self): pass# ############### 调用 ###############foo_obj = Foo()foo_obj.func()foo_obj.prop #调用属性
由属性的定义和调用要注意一下几点:
定义时,在普通方法的基础上添加@property装饰器;定义时,属性仅有一个self参数调用时,无需括号方法:foo_obj.func()
属性:foo_obj.prop
注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象
属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。
2、属性的两种定义方式
属性的定义有两种方式:
装饰器 即:在方法上应用装饰器静态字段 即:在类中定义值为property对象的静态字段装饰器方式:在类的普通方法上应用@property装饰器
我们知道Python中的类有经典类和新式类,新式类的属性比经典类的属性丰富。( 如果类继object,那么该类是新式类 )
经典类,具有一种@property装饰器(如上一步实例)
# ############### 定义 ############### class Goods: @property def price(self): return "xigang"# ############### 调用 ###############obj = Goods()result = obj.price # 自动执行 @property 修饰的 price 方法,并获取方法的返回值
新式类,具有三种@property装饰器
# ############### 定义 ###############class Goods(object): @property def price(self): print ‘@property‘ @price.setter def price(self, value): print ‘@price.setter‘ @price.deleter def price(self): print ‘@price.deleter‘# ############### 调用 ###############obj = Goods()obj.price # 自动执行 @property 修饰的 price 方法,并获取方法的返回值obj.price = 123 # 自动执行 @price.setter 修饰的 price 方法,并将 123 赋值给方法的参数del obj.price # 自动执行 @price.deleter 修饰的 price 方法
注:经典类中的属性只有一种访问方式,其对应被 @property 修饰的方法
新式类中的属性有三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter修饰的方法
类成员的修饰符
类的所有成员在上一步骤中已经做了详细的介绍,对于每一个类的成员而言都有两种形式:
公有成员,在任何地方都能访问私有成员,只有在类的内部才能方法私有成员和公有成员的定义不同:私有成员命名时,前两个字符是下划线。(特殊成员除外,例如:__init__、__call__、__dict__等)
12345 | class |
私有成员和公有成员的访问限制不同:
静态字段
公有静态字段:类可以访问;类内部可以访问;派生类中可以访问私有静态字段:仅类内部可以访问;class C: name = "公有静态字段" def func(self): print(C.name)class D(C): def show(self): print(C.name)C.name # 类访问obj = C()obj.func() # 类内部可以访问obj_son = D()obj_son.show() # 派生类中可以访问
class C: __name = "私有静态字段" def func(self): print C.__nameclass D(C): def show(self): print C.__nameC.__name # 类访问 ==> 错误obj = C()obj.func() # 类内部可以访问 ==> 正确obj_son = D()obj_son.show() # 派生类中可以访问 ==> 错误
反射实例
import sysclass WebServer: def __init__(self,host,port): self.host = host self.port = port def start(self): print(‘Server is starting...‘) def stop(self): print(‘Server is stopping...‘) def restart(self): self.stop() self.start()def test_run(self,name): print(‘running....‘,name,self.host)if __name__ == ‘__main__‘: server = WebServer(‘localhost‘,333) server2 = WebServer(‘localhost‘,333) if hasattr(server,sys.argv[1]): func = getattr(server,sys.argv[1]) func()
Socket
socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。
socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)
socket和file的区别:
file模块是针对某个指定文件进行【打开】【读写】【关闭】socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】服务端:
#!/usr/bin/env python# -*- coding:utf-8 -*-import socketip_port = (‘127.0.0.1‘,9999)sk = socket.socket()sk.bind(ip_port)sk.listen(5)while True: print(‘server waiting...‘) conn,addr = sk.accept() client_data = conn.recv(1024) print(client_data) conn.sendall(‘不要回答,不要回答,不要回答‘) conn.close()
客户端:
#!/usr/bin/env python# -*- coding:utf-8 -*-import socketip_port = (‘127.0.0.1‘,9999)sk = socket.socket()sk.connect(ip_port)sk.sendall(‘请求占领地球‘)server_reply = sk.recv(1024)print server_replysk.close()
WEB服务应用:
#!/usr/bin/env pythonimport socketdef handle_request(client): buf = client.recv(1024) client.send("HTTP/1.1 200 OK\r\n\r\n") client.send("Hello, World")def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((‘localhost‘,8080)) sock.listen(5) while True: connection, address = sock.accept() handle_request(connection) connection.close()if __name__ == ‘__main__‘: main()
Python学习笔记day7
相关内容
- 暂无相关文章
评论关闭