广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python的对象协议
  • 229
分享到

Python的对象协议

对象协议Python 2023-01-31 06:01:46 229人浏览 安东尼

Python 官方文档:入门教程 => 点击学习

摘要

    python是一门动态语言,Duck Typing概念遍布其中,所以其中的Concept并不是以类型的约束为载体,而是使用称作为协议的概念。那什么是Duck Typing呢?    Duck Typing是鸭子类型,在动态语言中用的

    python是一门动态语言,Duck Typing概念遍布其中,所以其中的Concept并不是以类型的约束为载体,而是使用称作为协议的概念。那什么是Duck Typing呢?

    Duck Typing是鸭子类型,在动态语言中用的较多,是动态类型语言设计的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口决定,而是由当前方法和属性的集合决定。说白了就是并不关心对象是什么类型,只关心行为。

    

    这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”可以这样表述:

    “当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

 在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。

看下面例子:

#coding=utf-8
class Duck:
    def quack(self):
        print u"嘎嘎嘎!"
    def feathers(self):
        print u"这是一只Duck。"

class Person:
    def quack(self):
        print u"hello,world!"
    def feathers(self):
        print u"这是人。"

def in_the_forest(duck):
    duck.quack()
    duck.feathers()

def game():
    donald = Duck()
    john = Person()
    in_the_forest(donald)
    in_the_forest(john)

game()

运行结果不用贴出来,都知道是什么。那么上面代码从何体现出Duck Typing风格呢?

    看看in_the_forest()函数,它对它的参数只有两个要求,那就是这个参数必须要有quack()和feathers()两个方法,不管它是什么类型,只要有这两个方法,都可以作为in_the_forest()函数的参数,而类Duck和Person都实现了这个方法,所以它们的实例都可以作为in_the_forest()的参数。这个就是鸭子类型,不关注对象类型本身,只关心行为。这一点更c++还是有很大区别的,我也学习过C++,也了解C++多态性以及虚函数所以感觉这差别还是蛮大的。

    现在来看看什么是协议吧,简单的说,在Python中我需要调用你的某个方法,你正好有这个方法,这就是协议,比如在加法运算中,当出现加号(+)时,那么按照数值类型相关的协议,python会自动去调用相应对象的__add__()方法,这就是协议。

python中有很多协议,比如下面代码:

#coding=utf-8
a = 1
print dir(a)

结果如下:

['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__fORMat__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']

上面代码中,a是整数对象,我们列出来该对象的所有属性,上面的属性列表中,以"__"开头并且以"__"结尾的基本上都是对象协议依赖的方法。是不是很多呀,我们可以将它们分成以下几类:

(1)类型转换协议

    类型转换协议,顾名思义就是用来进行类型转的咯,比如a=1,a是整型,想把它变成float浮点型,我们可以这样:

#coding=utf-8
a = 1
print type(a)
b = a.__float__()
print b
print type(b)

wKioL1fzqnzwH3kxAAAb5xZ86lE377.png-wh_50

当然你也可以用内置函数float()。

除了__float__()外,还有__str__()、__repr__()、__int__()、__long__()、__nonzero__()等等,这些都是类型转换协议依赖的方法。

在这里提下__nonzero__(),他用t于将类转换为布尔值。通常在用类进行判断和将类转换成布尔值时调用。通常会在if等条件语句会调用该方法。比如:

#coding=utf-8
list1 = []
if list1:
    print "1"

上面代码在执行过程中,先会调用list1对象的__nonzero__()方法,判读它是不是空,是的话就会转换为False。假设有些对类没有定义__nonzero__()方法,那么将如何判断真假呢?此时对象会获取__len__()方法,如果该方法返回值为0,则表示为假。

如果一个类即没有定义__nonzero__()方法,也没有定义__len__()方法,那么该类的所有实例用if判断的话全为真。

比如看下面例子:

#coding=utf-8
class A:
    def __nonzero__(self):
        print u"定义了__nonzero__()方法"
        return 1

class B:
    def __len__(self):
        print u"没定义__nonzero__()方法,但定义了__len__()方法"
        return 1

class C:
    pass

if A():
    a = 1
    print a
if B():
    a = 2
    print a
if C():
    a = 3
    print a

运行结果如下:

wKiom1fzsLezUZRqAAAmngDjIDs276.png-wh_50

希望上面的例子能够帮助你理解部分知识。


(2)用以比较大小的协议

这个协议依赖于__cmp__()方法,当两者相等时返回0,self<other时返回负值,反之返回正值。但是这种返回有点复杂,Python又定义了__eq__()、__ne__()、__lt__()、__gt__()等方法来实现相等、不等、小于和大于的判定。这也是Python对==,!=,<,>等操作符进行重载支撑的机制,也就是说重载这些操作符,就是要重新定义对应的方法。


(3)与数值类型相关的协议

这一类方法比较多,主要是数值之间的一些操作。

分类
方法操作符/函数说明







数值运算符

__add__+

__sub__

-
__mul__*
__div__/
__floordiv__//整除
__truediv__/真除法
__pow__**幂运算
__mod__%取余
__divmod__divmod()余、除






位运算符

__lshift__<<向左移位
__rshift__>>向右移位
__and__&
__or__|
__xor__^异或
__invert__~










运算赋值符

__iadd__+=
__isub__-=
__imul__*=
__idiv__/=
__ifloordiv__//=
__itruediv__/=
__ipow__**=
__imod__%=
__ilshift__<<=
__irshift__>>=
__iand__&=
__ior__|=
__ixor__^=


其它

__pos__+
__neg__-
__abs__abs()绝对值

举个例子,比如C++中,"<<"可表示输出流,我们也可以将python中"<<"重载为具有输出流功能。代码如下:

#coding=utf-8
class endl(object):
    pass
class Cout(object):
    def __lshift__(self, other):
        if other is endl:
            print
            return
        print other
        return self
cout = Cout()
cout << "hello" << "world" << endl

运行结果如下:

wKioL1f0stDBrUuSAAAaZUbhgYw364.png-wh_50

不过在python中,将"<<"操作符重载为具有输出流功能,基本上是没有意义,在这里只是举例说明。

另外Python中还有一个特有的概念:反运算。例如a + b,调用的是a的__add__()方法,如果a没有__add__()方法,但b有,可是这种写法调用b.__add__()又不对的,这时候Python有了一个反运算协议,它会去检测b中有没有__radd__(),如果有的话,那么a为参数调用之。类似__radd__()方法,所有数值运算和位运算都之处,规则一律在前面加前缀r。


(4)容器类协议

既然为容器,那么肯定会有查询、取值、删除、赋值、求长度等等一系列动作行为,那么必有对应的方法与这些操作对应。打印出dir(list)的值,结果如下:

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

其中:

求长度,也就是查询容器内有多少个对象,用__len__()方法,内置函数len()就是通过该方法实现的。

取值、删除、赋值依次对应__getitem__()、__delitem__()、__setitem__(),有些容器没有__setitem__(),比如字符串,应为字符串是不可变对象

__iter__()实现了迭代协议,__reversed__()则提供了对内置函数reversed()的支持,用来排序

还有成员关系判定符in和not in,对应的方法是__contains__()


(5)可调用对象协议

可调用对象,也就是类似函数对象,能够让类实例表现的像函数一样,这样可以让每一个函数调用都有所不同。怎么理解这句话呢?还是看例子吧。

#coding=utf-8
class A(object):
    def __init__(self,name):
        self.name = name
    def __call__(self):
        print "dongn something with %s"%(self.name)

a = A('li lei')
b = A('han ×××')
print a()
print b()

运行结果如下:

wKioL1fzxLvz9_mYAAAehdrZUyE354.png-wh_50

看看上面的例子,我们能够像调用函数一样调用实例

对象通过提供__call__(slef, [,*args [,**kwargs]])方法可以模拟函数的行为,如果一个对象x提供了该方法,就可以像函数一样使用它,也就是说x(arg1, arg2...) 等同于调用x.__call__(self, arg1, arg2) 。


(6)哈希协议

如果对象有__hash__()方法,表示是一个可哈希对象。__hash__()方法支持这hash()这个内置函数。按照文档里面的解释“如果一个对象是可哈希的,那么在它的生存期内必须不可变(需要一个哈希函数),而且可以和其他对象比较(需要比较方法).比较值相同的对象一定有相同的哈希值”。

    这也就是说所有不可变的内置类型t都是可哈希的,比如string,tuple。所有可变的内置类型都是不可哈希的,比如list,dict(即没有__hash__()方法)。字典的key必须是可哈希的,所以tuple,string可以做key,而list不能做key。


(7)上下文管理器协议

这个在之前的博文中讲过,在此不做过多解释,可参考之前的相关博文。Http://11026142.blog.51cto.com/11016142/1845862


--结束END--

本文标题: Python的对象协议

本文链接: https://www.lsjlt.com/news/190335.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python的对象协议
        Python是一门动态语言,Duck Typing概念遍布其中,所以其中的Concept并不是以类型的约束为载体,而是使用称作为协议的概念。那什么是Duck Typing呢?    Duck Typing是鸭子类型,在动态语言中用的...
    99+
    2023-01-31
    对象 协议 Python
  • WebSocket协议与TCP协议的对比与选择
    在网络通信中,TCP协议是一种可靠的传输协议,广泛应用于各种网络通信场景。而WebSocket协议则是一种基于HTTP的应用层协议,它提供了双向通信的能力,使得客户端和服务器之间可以实时地进行数据交互。本文将对WebSocket协议和TCP...
    99+
    2023-10-21
    它提供可靠的数据传输 错误检测和拥塞控制。
  • PHP phar:协议对象注入技术介绍
    前言在之前的BlackHat 2018大会上公布了一款针对PHP应用程序的全新攻击技术。我们将通过这篇文章简单介绍下。来自Secarma的安全研究员Sam Thomas发现了一种新的开发技术,它可以导致PHP对象注入漏洞——而无需使用PHP...
    99+
    2023-06-04
  • Python中的端口协议之基于UDP协议
    UDP协议:   1、python中基于udp协议的客户端与服务端通信简单过程实现   2、udp协议的一些特点(与tcp协议的比较)        3、利用socketserver模块实现udp传输协议的并发通信 -----------...
    99+
    2023-01-31
    协议 端口 Python
  • Java Socket如何使用加密协议传输对象
    本篇文章为大家展示了Java Socket如何使用加密协议传输对象,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。前面几篇博文提到了Socket中一些常用的用法,但是对于一些有安全要求的应用就需要加密...
    99+
    2023-06-17
  • Python的迭代器协议
        迭代器是Python中的一个高级概念,迭代器是一个实现了迭代器协议的对象,那何为迭代器协议呢?满足下面两个条件就行。(1)该对象实现了__iter__()方法;(2)该对象实现了next()方法,返回当前元素,并指向下一个元素的位置...
    99+
    2023-01-31
    协议 迭代 Python
  • 为什么HTTP协议对于UNIX系统中的ASP对象至关重要?
    HTTP协议是一种被广泛应用的网络协议,它的出现使得互联网上的信息传输更加快捷、高效。而在UNIX系统中,ASP对象的使用同样离不开HTTP协议。本文将从HTTP协议与ASP对象的关系出发,介绍HTTP协议在UNIX系统中的重要性。 首先,...
    99+
    2023-07-27
    对象 unix http
  • Java Socket使用加密协议进行传输对象的方法
    本文实例讲述了Java Socket使用加密协议进行传输对象的方法。分享给大家供大家参考,具体如下:前面的几篇文章介绍了Socket中一些常见的用法,但是对于一些有安全要求的应用就需要加密传输的数据,此时就需要用到SSLSocket了。还是...
    99+
    2023-05-31
    java socket ava
  • HTTP协议(9)Python requ
    通过Python中的requests模块也可以来发送HTTP请求,接收HTTP响应,从而实现一些更加灵活的操作。requests是第三方库,不过在Kali中已经自带了该模块。Python3和Python2的用法稍微有些差别,这里先以Pyth...
    99+
    2023-01-31
    协议 HTTP requ
  • Python中TCP协议的理解
    Test01–>TCP客户端案例 #! /usr/bin/env python3 # -*- coding:utf-8 -*- from socket import * def main(): # 1.创...
    99+
    2023-01-31
    协议 Python TCP
  • python实现onvif协议-2
    from suds.client import Client from suds.wsse import Security from suds_pa...
    99+
    2023-01-31
    协议 python onvif
  • Python Web开发中的WSGI协议
     在Python Web开发中,我们一般使用Flask、Django等web框架来开发应用程序,生产环境中将应用部署到Apache、Nginx等web服务器时,还需要uWSGI或者Gunicorn。一个完整的部署应该类似这样: Web ...
    99+
    2023-01-31
    协议 Python Web
  • Python中SSH协议的实现 - Pa
    操作系统维护时, 一般会通过ssh命令连接到远端服务器, 进行某些操作. 那Python中如何完成这些呢, 当然也能执行ssh命令, 但还有更优雅的方式, 借助Paramiko, 其为实现了SSHv2协议的一开源项目, 下面主要使用了它的s...
    99+
    2023-01-31
    协议 Python SSH
  • netty对proxyprotocol代理协议的支持详解
    目录简介netty对proxy protocol协议的支持HAProxyMessage的编码解码器netty中proxy protocol的代码示例总结简介 我们知道proxy pr...
    99+
    2022-11-13
  • WebSocket协议与HTTP协议的差异与联系
    引言:随着互联网的普及,Web应用的需求不断增加,为了实现实时交互和推送功能,新的通信协议WebSocket应运而生。而传统的HTTP协议也在这个过程中逐渐被WebSocket取代。本文将重点探讨WebSocket协议与HTTP协议的差异与...
    99+
    2023-10-21
    Http websocket 差异与联系
  • mqtt协议和tcp协议的区别有哪些
    小编给大家分享一下mqtt协议和tcp协议的区别有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!区别:1、MQTT诞生于1999年互联网初期,TCP协议诞生于...
    99+
    2023-06-15
  • Python 协程与 JavaScript 协程的对比
    目录1、前言2、什么是协程?3、混乱的历史3.1Python协程的进化4、JavaScript协程的进化5、Python协程成熟体5.1协程(coroutine)5.2任务(Task...
    99+
    2022-11-12
  • python 网络通信协议/TCP,UD
    一.osi七层协议 互联网协议按照功能不同分为osi七层或tcp/ip五层或tcp/ip四层 协议具体内容   各层的功能简述: 【1】物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率...
    99+
    2023-01-30
    通信协议 网络 python
  • Python网络编程之HTTP协议的python应用
    目录搭建python自带静态web服务器1. 静态Web服务器是什么?2. 如何搭建Python自带的静态Web服务器3. 访问搭建的静态Web服务器4. 查看浏览器和搭建的静态We...
    99+
    2022-11-13
    python http协议 http协议python应用 python网络编程 python使用http协议
  • SSRF(3)伪协议读取文件&Gopher协议的利用
    一:Http、Dict和file等协议的利用 1,内网访问 所以构造: /url=http://127.0.0.1/flag.php 得到: ctfhub{ce475b59a4baee959112777b} 2,伪协议读取文件 最经...
    99+
    2023-10-01
    php 开发语言 web安全 网络
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作