文章目录

  • 1. 静态方法、类方法
    • 1.1 静态方法
    • 1.2 类方法
  • 2. 属性方法
  • 3. 类的一些成员方法
  • 4. 反射
  • 5. 异常处理
  • 6. socket 套接字

1. 静态方法、类方法

1.1 静态方法

  通过 @staticmethod 装饰器即可把其装饰的方法变为一个静态方法,静态方法就是普通的方法,可以在实例化后直接调用,并且在方法里可以通过 self. 调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法。

class Dog(object):def __init__(self,name):self.name = name@staticmethod #把eat方法变为静态方法def eat(self):print("%s is eating" % self.name)d = Dog("yle")
d.eat()

  上面的调用会报错,说是eat需要一个self参数,但调用时却没有传递,没错,当eat变成静态方法后,再通过实例调用时就不会自动把实例本身当作一个参数传给self了。

想让上面的代码可以正常工作有两种办法:

  1. 调用时主动传递实例本身给 eat 方法,即 d.eat(d)

  2. 在eat方法中去掉 self 参数,但这也意味着,在 eat 中不能通过 self. 调用实例中的其它变量了

1.2 类方法

  类方法通过 @classmethod 装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量

class Dog(object):def __init__(self,name):self.name = name@classmethoddef eat(self):print("%s is eating" % self.name)d = Dog("yle")
d.eat()

执行报错如下,说Dog没有name属性,因为name是个实例变量,类方法是不能访问实例变量的。
此时可以定义一个类变量,也叫name,看下执行效果:

class Dog(object):name = "我是类变量"def __init__(self,name):self.name = name@classmethoddef eat(self):print("%s is eating" % self.name)d = Dog("yle")
d.eat()#执行结果
我是类变量 is eating

2. 属性方法

属性方法的作用就是通过 @property 装饰器把一个方法变成一个静态属性。

class Dog(object):name = "我是类变量"def __init__(self,name):self.name = name@classmethoddef eat(self):print("%s is eating" % self.name)d = Dog("yle")
d.eat()

  调用会报错, 说 NoneType is not callable, 因为 eat 此时已经变成一个静态属性了, 不是方法了, 想调用已经不需要加 () 号了,直接 d.eat 就可以了。

d = Dog("yle")
d.eat#输出yle is eating

关于属性方法,一个场景如下:
  你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:

  1. 连接航空公司API查询

  2. 对查询结果进行解析

  3. 返回结果给你的用户

  因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以。

class Flight(object):def __init__(self,name):self.flight_name = namedef checking_status(self):print("checking flight %s status " % self.flight_name)return  1@propertydef flight_status(self):status = self.checking_status()if status == 0 :print("flight got canceled...")elif status == 1 :print("flight is arrived...")elif status == 2:print("flight has departured already...")else:print("cannot confirm the flight status...,please check later")@flight_status.setter #修改def flight_status(self,status):status_dic = {: "canceled",:"arrived",: "departured"}print("\033[31;1mHas changed the flight status to \033[0m",status_dic.get(status) )@flight_status.deleter  #删除def flight_status(self):print("status got removed...")f = Flight("CA980")
f.flight_status
f.flight_status =  2 #触发@flight_status.setter
del f.flight_status #触发@flight_status.deleter

3. 类的一些成员方法

1)__doc __ 表示类的描述信息

class Foo:""" 描述类信息,这是用于看片的神奇 """def func(self):passprint(Foo.__doc__)

2)__ module__ 和 __ class__

  • __ module__ 表示当前操作的对象在那个模块
  • __ class__ 表示当前操作的对象的类是什么

有两个文件:

class C:def __init__(self):self.name = 'wupeiqi'
from lib.aa import Cobj = C()
print obj.__module__  # 输出 lib.aa,即:输出模块
print obj.__class__      # 输出 lib.aa.C,即:输出类

3.)__ init__ 构造方法,通过类创建对象时,自动触发执行

4)__ del__ 析构方法,当对象在内存中被释放时,自动触发执行

  此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

5)__ call__ 对象后面加括号,触发执行

  构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __ call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:def __init__(self):passdef __call__(self, *args, **kwargs):print('__call__')obj = Foo() # 执行 __init__
obj()       # 执行 __call__

6) __ dict__ 查看类或对象中的所有成员

class Province:country = 'China'def __init__(self, name, count):self.name = nameself.count = countdef 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'}

7)__ str__ 如果一个类中定义了__ str__方法,那么在打印对象时,默认输出该方法的返回值

class Foo:def __str__(self):return 'yleave'obj = Foo()
print obj
# 输出:yleave

8)__ getitem__、__ setitem__、__ delitem__
用于索引操作,如字典。以上分别表示获取、设置、删除数据

class Foo(object):def __getitem__(self, key):print('__getitem__',key)def __setitem__(self, key, value):print('__setitem__',key,value)def __delitem__(self, key):print('__delitem__',key)obj = Foo()result = obj['k1']      # 自动触发执行 __getitem__
obj['k2'] = 'yle'   # 自动触发执行 __setitem__
del obj['k1']   #自动触发 __delitem__

9.)__ new__ 、__ metaclass__

class Foo(object):def __init__(self,name):self.name = namef = Foo("yle")

  上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象。

  如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

print type(f) # 输出:<class '__main__.Foo'>     表示,obj 对象由Foo类创建
print type(Foo) # 输出:<type 'type'>              表示,Foo类对象由 type 类创建

  所以,f对象是Foo类的一个实例,Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。

那么,创建类就可以有两种方式:

1)普通方式:

class Foo(object):def func(self):print 'hello world'

2)特殊方式:

def func(self):print 'hello world'Foo = type('Foo',(object,), {'func1': func})
#type第一个参数:类名
#type第二个参数:当前类的基类
#type第三个参数:类的成员

加上构造方法:

def func(self):print("hello %s"%self.name)def __init__(self,name,age):self.name = nameself.age = age
Foo = type('Foo',(object,),{'func':func,'__init__':__init__})f = Foo("jack",22)
f.func()

So ,类 是由 type 类实例化产生

那么问题来了,类默认是由 type 类实例化产生,type类中如何实现的创建类?类又是如何创建对象?

答:类中有一个属性 __ metaclass__,其用来表示该类由 谁 来实例化创建,所以,我们可以为 __ metaclass__ 设置一个type类的派生类,从而查看 类 创建的过程。

class MyType(type):def __init__(self,*args,**kwargs):print("Mytype __init__",*args,**kwargs)def __call__(self, *args, **kwargs):print("Mytype __call__", *args, **kwargs)obj = self.__new__(self)print("obj ",obj,*args, **kwargs)print(self)self.__init__(obj,*args, **kwargs)return objdef __new__(cls, *args, **kwargs):print("Mytype __new__",*args,**kwargs)return type.__new__(cls, *args, **kwargs)print('here...')
class Foo(object,metaclass=MyType):def __init__(self,name):self.name = nameprint("Foo __init__")def __new__(cls, *args, **kwargs):print("Foo __new__",cls, *args, **kwargs)return object.__new__(cls)f = Foo("yle")
print("f",f)
print("fname",f.name)

程序运行结果:

here...
Mytype __new__ Foo (<class 'object'>,) {'__module__': '__main__', '__qualname__': 'Foo', '__init__': <function Foo.__init__ at 0x00B4AE40>, '__new__': <function Foo.__new__ at 0x00B4ADF8>}
Mytype __init__ Foo (<class 'object'>,) {'__module__': '__main__', '__qualname__': 'Foo', '__init__': <function Foo.__init__ at 0x00B4AE40>, '__new__': <function Foo.__new__ at 0x00B4ADF8>}
Mytype __call__ yle
Foo __new__ <class '__main__.Foo'>
obj  <__main__.Foo object at 0x00B45F10> yle
<class '__main__.Foo'>
Foo __init__
f <__main__.Foo object at 0x00B45F10>
fname yle

类的生成 调用 顺序依次是 __ new__ --> __ init__ --> __ call__

4. 反射

python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数

下列方法适用于类和对象(一切皆对象,类本身也是一个对象):

1)getattr(obj, name_str, default=None)
根据字符串 name_str 去获取 obj 对象里的对应的方法的内存地址

2)hasattr(obj,name_str)
判断一个对象 obj 里是否有对应的 name_str 字符串的方法

3)setattr(obj,‘y’,v)
相当于 obj.y = v

4)delattr(obj,name_str)

示例:

class Dog(object):def __init__(self,name):self.name = namedef eat(self,food):print('%s is eating...%s'%(self.name,food))def bulk(self):print('%s is yelling...'%self.name)d = Dog('zhang')
choice = input('>>:').strip()if hasattr(d,choice):func = getattr(d,choice)func('pie')
else:'''设置方法setattr(d,choice,bulk)d.talk(d)'''#设置属性setattr(d,choice,22)print(getattr(d,choice))

程序运行结果:

1:
>>:eat
zhang is eating...pie2:
>>:age   #名字任意输
223:
>>:talk
zhang is yelling...

5. 异常处理

参考:https://www.cnblogs.com/wupeiqi/articles/5017742.html

6. socket 套接字

  socket本质上就是在2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递。 我们知道网络 通信 都 是基于 ip+port 方能定位到目标的具体机器上的具体服务,操作系统有0-65535个端口,每个端口都可以独立对外提供服务,如果 把一个公司比做一台电脑 ,那公司的总机号码就相当于ip地址, 每个员工的分机号就相当于端口, 你想找公司某个人,必须 先打电话到总机,然后再转分机 。

  建立一个socket必须至少有2端, 一个服务端,一个客户端, 服务端被动等待并接收请求,客户端主动发起请求, 连接建立之后,双方可以互发数据。

示例:

服务端:

import socketserver = socket.socket()
server.bind(('localhost',6969)) #绑定监听端口
server.listen() #监听while True:print('准备开始接收数据')conn,addr = server.accept() #等待信息print(conn)  #conn 就是客户端连过来而在服务端为期生成的一个连接实例print(addr)print('数据来了')while True:data = conn.recv(4096)print('recv2:',data.decode())if not data:print('client has lost...')breakconn.send(data.upper())server.close()

客户端:

import socketclient = socket.socket() #声明 socket 类型,同时生成 socket 连接对象
client.connect(('localhost',6969))
while True:data = input('>>:')client.send(data.encode('utf-8'))data1 = client.recv(4096)print("recv1:",data1.decode())client.close()

更多参考:
https://www.cnblogs.com/wupeiqi/articles/5040823.html
https://www.cnblogs.com/linhaifeng/articles/6129246.html#_label6

day7 面向对象进阶、socket套接字相关推荐

  1. 计算机网络(二) | 网络编程基础、Socket套接字、UDP和TCP套接字编程

    目录 一.网络编程基础 1.1 为什么需要网络编程 1.2 什么是网络编程 1.3 网络编程中的基本概念 二.Socket套接字 2.1 概念 2.2 分类 2.3 Java数据报套接字通信模型 2. ...

  2. 三、初识Socket套接字结构体

    一.初识Socket套接字结构体 1.通用套接字结构体类型 struct sockaddr{sa_family_t sa_family; //协议簇char sa_data[14]; //协议簇数据} ...

  3. 基于UDP协议的socket套接字编程 基于socketserver实现并发的socket编程

    基于UDP协议 的socket套接字编程 1.UDP套接字简单示例 1.1服务端 import socketserver = socket.socket(socket.AF_INET,socket.S ...

  4. Python 技术篇-socket套接字实现两个窗口间消息传递实例演示,TCP实现

    上一篇:Python 技术篇-socket 套接字实现服务器客户端消息传递,UDP 实现 本篇介绍用 TCP 来实现. socket 实现客户端服务器的消息传递有 TCP 和 UDP 两种方式. TC ...

  5. Python 技术篇-socket套接字实现服务器客户端消息传递实例演示,UDP实现

    上一篇:Python 技术篇-socket 套接字实现两个窗口间消息传递,TCP 实现 本篇介绍用 UDP 来实现. socket 套接字实现服务器客户端消息传递有 UDP 和 TCP 两种形式.他们 ...

  6. java实现套接字网络编程_Java网络编程(一)Socket套接字

    一.基础知识 1.TCP:传输控制协议. 2.UDP:用户数据报协议. 二.IP地址封装 1.InetAddress类的常用方法 getLocalHost() 返回本地主机的InetAddress对象 ...

  7. C语言socket bind()函数(为socket套接字关联了一个相应的地址与端口号)

    #include <sys/socket.h>int bind(int socket, const struct sockaddr *address, socklen_t address_ ...

  8. Python开发基础----异常处理、socket套接字基础1

    异常处理 错误 程序里的错误一般分为两种: 1.语法错误,这种错误,根本过不了python解释器的语法检测,必须在程序执行前就改正 2.逻辑错误,人为造成的错误,如数据类型错误.调用方法错误等,这些解 ...

  9. socket 套接字的基本概念

    什么是套接字: socket套接字:一套网络通信的接口 (API), 一套函数, 本质是伪文件. 在网络环境中唯一的标识一个进程需要 IP 和端口,这个进程就是 socket,因此 socket 需要 ...

最新文章

  1. 在Ubuntu下怎么截图
  2. java中的wait和sleep_java中wait和sleep的区别
  3. 3.关于QT中的MainWindow窗口,MenuBar,ToolBar,QuickTip等方面的知识点
  4. AtCoder Grand Contest 008: Contiguous Repainting(思维)
  5. 来给你20个优秀的......前端轮播图插件
  6. SK-Learn使用NMF(非负矩阵分解)和LDA(隐含狄利克雷分布)进行话题抽取
  7. python开源系统_搭建轻量级的开源推荐系统-Python-recsys
  8. 用多媒体库 Bass.dll 播放 mp3 [8] - 实时显示左右声道的峰值
  9. EFI下WIN8.1和Ubuntu的双系统安装
  10. MessageBox和AfxMessageBox函数的区别
  11. 词汇的积累 —— 反义词、同义词
  12. 【CCCC】L3-023 计算图 (30分),dfs搜索+偏导数计算
  13. 视频帧AI分析后编码
  14. 1.Prometheus 监控技术与实践 --- 云计算时代的监控系统
  15. Spark Mllib里如何删除每一条数据中所有的双引号“”(图文详解)
  16. 调起百度地图客户端之导航功能
  17. 抖音短视频的营销模式
  18. 会议论文投稿到接收流程【手里有粮心中不慌】
  19. miner配置文件详解
  20. VS2017 专业版 离线安装实践 Visual Studio 2017

热门文章

  1. 微服务失败的11个原因
  2. 2021 年架构技术面试大厂高频题汇总(附答案详解)
  3. 阿里程序员连续两次绩效3.25!大老板威胁要开除他!还不给赔偿金!问大家该如何维权?...
  4. 斐波那契数列的四种实现
  5. 查询太慢?看看ES是如何把索引的性能压榨到极致的!
  6. 不能精准定位bug?可能是你没get到这几个打印日志的诀窍!
  7. 计算机视觉算法工程师(旷视、商汤、智云、海康)面试总结
  8. Iaas、Caas、Paas、Faas!选择正确的平台!
  9. 2019年一线大厂20个长问mongo面试题和答案
  10. 程序员吐槽职场戏精:凌晨三点半发周报,太装了!