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__等)

12345classC:def__init__(self):self.name=‘公有字段‘self.__foo="私有字段"

私有成员和公有成员的访问限制不同

静态字段

公有静态字段:类可以访问;类内部可以访问;派生类中可以访问私有静态字段:仅类内部可以访问;
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

相关内容

    暂无相关文章

评论关闭