python-python基础7
本章内容:
- 静态方法
- 类方法
- 属性方法
- 类的特殊成员方法
- 反射
- 异常处理
- 动态导入模块importlib
- socket编程
一、静态方法
通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法
class Dog(object):
def __init__(self, name):
self.name = name
@staticmethod # 把eat方法变为静态方法,和它所属的类没有关系了
def eat(name,food):
print("%s is eating %s" %(name,food)) d = Dog("gougou")
d.eat("gougou","shi")
执行结果:
gougou is eating shi
实际上在静态方法里访问不了类或实例中的任何属性
二、类方法
类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量
class Dog(object):
name="aaa"
def __init__(self, name):
self.name = name
@classmethod
def eat(self):
print("%s is eating" %self.name) d = Dog("guogou")
d.eat()
执行结果:
aaa is eating
看上面这个例子,实例化Dog这个类的时候,传了参数name=gougou,在下面eat()方法前加了@classmethod类方法,那么eat()这个方法就不能访问实例变量,也就是不能访问name=gougou,传给eat()的参数只能是在类里定义的参数name=aaa。
三、属性方法
属性方法的作用就是通过@property把一个方法变成一个静态属性,如果要给这个属性赋值,用@flight_status.setter
把一个方法变成静态属性有什么用呢?既然想要静态变量,那直接定义成一个静态变量不就得了么?well, 以后你会需到很多场景是不能简单通过 定义 静态属性来实现的, 比如 ,你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:
1. 连接航空公司API查询
2. 对查询结果进行解析
3. 返回结果给你的用户
因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以。(用户只要一个返回的属性值,而不要调用方法,隐藏实现细节)
class Flight(object):
def __init__(self,name):
self.flight_name = name def checking_status(self):
print("checking flight %s status " % self.flight_name)
return 1 @property
def flight_status(self):
status = self.checking_status()
if status == 0 :
print("{0} flight got canceled...".format(self.flight_name))
elif status == 1 :
print("{0} flight is arrived...".format(self.flight_name))
elif status == 2:
print("{0} flight has departured already...".format(self.flight_name))
else:
print("cannot confirm the flight status...,please check later") f = Flight("CA980")
f.flight_status
执行结果:
checking flight CA980 status
CA980 flight is arrived...
当我想改状态的时候:
class Flight(object):
fl_status=1
def __init__(self,name):
self.flight_name = name def checking_status(self):
print("checking flight %s status " % self.flight_name)
return self.fl_status @property
def flight_status(self):
status = self.checking_status()
if status == 0 :
print("{0} flight got canceled...".format(self.flight_name))
elif status == 1 :
print("{0} flight is arrived...".format(self.flight_name))
elif status == 2:
print("{0} flight has departured already...".format(self.flight_name))
else:
print("cannot confirm the flight status...,please check later") @flight_status.setter
def flight_status(self,ch_status):
print("The status of {0} is changed to {1}...".format(self.flight_name,ch_status))
self.fl_status=ch_status f = Flight("CA980")
f.flight_status
f.flight_status=0
f.flight_status
执行结果:
checking flight CA980 status
CA980 flight is arrived...
The status of CA980 is changed to 0...
checking flight CA980 status
CA980 flight got canceled...
四、类的特殊成员方法
1、__doc__:表示类的描述信息
class Dog(object):
'''这是描述一个狗的类'''
name="aaa"
def __init__(self, name):
self.name = name
def eat(self):
print("%s is eating" %self.name) print(Dog.__doc__)
执行结果:
这是描述一个狗的类
2. __module__ 和 __class__
__module__ 表示当前操作的对象在哪个模块
__class__ 表示当前操作的对象的类是什么
3.__call__ 对象后面加括号,触发执行。
注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
class Dog(object):
'''这是描述一个狗的类'''
name="aaa"
def __init__(self, name):
self.name = name
def eat(self):
print("%s is eating" %self.name)
def __call__(self, *args, **kwargs):
print("running call") d=Dog("wangwang")
d()
执行结果:
running call
4.__dict__ 打印类或者实例里的所有属性和方法
class Dog(object):
'''这是描述一个狗的类'''
name="aaa"
def __init__(self, name):
self.name = name
def eat(self):
print("%s is eating" %self.name)
def __call__(self, *args, **kwargs):
print("running call") print(Dog.__dict__) #打印类里的所有属性和方法,不包括实例属性和方法
d=Dog("wangwang")
print(d.__dict__) #打印实例属性和方法
执行结果:
{'__module__': '__main__', '__doc__': '这是描述一个狗的类', 'name': 'aaa', '__init__': <function Dog.__init__ at 0x000002457F8AC820>, 'eat': <function Dog.eat at 0x000002457F8AC8B0>, '__call__': <function Dog.__call__ at 0x000002457F8AC940>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>}
{'name': 'wangwang'}
5.__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
class Dog(object):
'''这是描述一个狗的类'''
name="aaa"
def __init__(self, name):
self.name = name
def eat(self):
print("%s is eating" %self.name)
def __call__(self, *args, **kwargs):
print("running call")
def __str__(self):
return "{0} is a dog".format(self.name) d=Dog("wangwang")
print(d)
执行结果:
wangwang is a dog
6.__getitem__、__setitem__、__delitem__
用于索引操作,如字典。以上分别表示获取、设置、删除数据
就是把一个实例对象让外部调用的人看上去是一个字典,能赋值,能调用,能删除,但是外部对这个“字典”的每个操作都可以在类里的方法定义相关的操作,比如外部想删除这个“字典”里的某个值,在函数里可以定义删除这个操作,告诉外部不能删。
class Foo(object):
def __init__(self):
self.data={}
def __getitem__(self,key):
# print('in __getitem__')
return self.data[key] def __setitem__(self, key, value):
# print('__setitem__', key, value)
self.data[key]=value def __delitem__(self, key):
print('{0}不能删'.format(key)) obj = Foo()
obj["name"]="jehu"
obj["age"]=25
print(obj["name"])
print(obj["age"])
del obj["age"]
执行结果:
jehu
25
age不能删
五、反射
通过字符串映射或修改程序运行时的状态、属性、方法, 有以下4个方法
hasattr(obj,str):判断obj这个对象里是否包含名为str的属性或方法,str是字符串格式
getattr(obj,str)():调用obj对象里的名为str的方法,如果str在对象里是一个属性,那么后面就不用加(),getattr(obj,str)
setattr(obj,'y',v):obj.y=v,把v这个方法或者属性赋值给obj.y(给obj这个对象添加一个新的属性方法v)
delattr(obj,str):删除类里的成员
class human(object):
def __init__(self,name,age):
self.name=name
self.age=age
def sheep(self):
print("{0} is sleeping...".format(self.name))
def eat(self,food):
print("{0} is eating {1}".format(self.name,food))
def nothing(self):
print("Do nothing...") def changes(self):
print("{0} is changing...".format(self.name)) h=human("jehu",25)
choice=input(">>:")
if hasattr(h,choice): #判断h这个实例里有没有choice这个方法
getattr(h,choice)() #如果有就执行h.choice()
else:
setattr(h,choice,changes) #h.choice=changes
getattr(h,choice)(h) #change(h)
执行结果:
输入sleep,打印jehu is sleeping...
输入sss,打印jehu is changing...
六、异常处理
1、异常基础
在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!!
data={"name":"jehu","age":25} try:
data["addr"]
except KeyError as e:
print("输入的key不存在")
执行结果:
输入的key不存在
data={"name":"jehu","age":25} try:
data["addr"]
except Exception as e: #抓住所有类型的错误,e就是错误类型
print("出错了",e)
执行结果:
出错了: 'addr'
try:
open("www","r")
except IndexError as e:
print("列表操作错误:",e)
except KeyError as e:
print("没有这个key",e)
except Exception as e:
print("未知错误:",e)
else:
print("一切正常")
执行结果:
未知错误: [Errno 2] No such file or directory: 'www'
try:
a=1
print(a)
except IndexError as e:
print("列表操作错误:",e)
except KeyError as e:
print("没有这个key",e)
except Exception as e:
print("未知错误:",e)
else:
print("一切正常") finally:
print("不管有没有错,都执行")
执行结果:
1
一切正常
不管有没有错,都执行
2、异常种类
python中的异常种类非常多,每个异常专门用于处理某一项异常!!!
AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError 输入/输出异常;基本上是无法打开文件
ImportError 无法引入模块或包;基本上是路径问题或名称错误
IndentationError 语法错误(的子类) ;代码没有正确对齐
IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError 试图访问字典里不存在的键
KeyboardInterrupt Ctrl+C被按下
NameError 使用一个还未被赋予对象的变量
SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
TypeError 传入对象类型与要求的不符合
UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
导致你以为正在访问它
ValueError 传入一个调用者不期望的值,即使值的类型是正确的
3、主动触发异常
try:
raise Exception('错误了。。。')
except Exception as e:
print(e)
4、自定义异常
class JehuException(Exception):
def __init__(self,msg):
self.msg=msg
def __str__(self):
return self.msg try:
raise JehuException("数据库无法连接")
except JehuException as e:
print(e)
执行结果:
数据库无法连接
七、动态导入模块
importlib
示例:创建一个名为immp的目录,在这个目录下创建一个名为Kobe的python文件:
class basketball(object):
def __init__(self):
self.name="kobe"
然后在immp的同级目录下创建一个python文件,想要导入Kobe这个模块
import importlib
immp=importlib.import_module('immp.Kobe')
print(immp.basketball().name)
意思就是可以用importlib导入字符串格式的模块
八、socket编程
来看一个简单的socket编程示例:
服务端:
import socket server=socket.socket()
server.bind(("localhost",6969)) #bind只能接收一个值,所以传进去的是一个元组:ip和端口号
server.listen()
print("我正在监听...") con,addr=server.accept()
#server.accept传的是两个值,con:客户端连接过来,服务端为其生成的一个连接实例,addr:套接字
print(con,addr)
print("连接成功") while True:
data=con.recv(1024) #参数的含义是缓冲区大小,能接受多少字节的数据
data_decode=data.decode()
text="我收到的数据是:{0},from {1}".format(data_decode,addr)
con.send(text.encode()) server.close()
客户端:
import socket client=socket.socket() #生成socket实例
client.connect(("localhost",6969)) #bind只能接收一个值,所以传进去的是一个元组:ip和端口号 while True:
#client.send(b'hello world!') 数据转换成bytes格式的另一种方法
text=input("Input:")
if len(text) == 0 : #发送的数据不能为空
continue
#需要把发送的数据转换成bytes格式
client.send(text.encode()) data=client.recv(1024)
print("revc:",data.decode()) client.close()
部分字段解析:
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
参数一:地址簇
socket.AF_INET IPv4(默认)
socket.AF_INET6 IPv6socket.AF_UNIX 只能够用于单一的Unix系统进程间通信
参数二:类型
socket.SOCK_STREAM 流式socket , for TCP (默认)
socket.SOCK_DGRAM 数据报式socket , for UDPsocket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
socket.SOCK_RDM 是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
socket.SOCK_SEQPACKET 可靠的连续数据包服务参数三:协议
0 (默认)与特定的地址家族相关的协议,如果是 0 ,则系统就会根据地址格式和套接类别,自动选择一个合适的协议
sk.bind(address)
s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。
sk.listen(backlog)
开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。
backlog等于5,表示内核已经接到了连接请求,但服务器还没有调用accept进行处理的连接个数最大为5
这个值不能无限大,因为要在内核中维护连接队列
sk.setblocking(bool)
是否阻塞(默认True),如果设置False,那么accept和recv时一旦无数据,则报错。
sk.accept()
接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。
接收TCP 客户的连接(阻塞式)等待连接的到来
sk.connect(address)
连接到address处的套接字。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
sk.connect_ex(address)
同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061
sk.close()
关闭套接字
sk.recv(bufsize[,flag])
接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。flag提供有关消息的其他信息,通常可以忽略。
sk.recvfrom(bufsize[.flag])
与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。
sk.send(string[,flag])
将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。
sk.sendall(string[,flag])
将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
内部通过递归调用send,将所有内容发送出去。
sk.sendto(string[,flag],address)
将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。该函数主要用于UDP协议。
sk.settimeout(timeout)
设置套接字操作的超时期,timeout是一个浮点数,单位是秒。值为None表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如 client 连接最多等待5s )
sk.getpeername()
返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
sk.getsockname()
返回套接字自己的地址。通常是一个元组(ipaddr,port)
sk.fileno()
套接字的文件描述符
python-python基础7的更多相关文章
- Python文件基础
===========Python文件基础========= 写,先写在了IO buffer了,所以要及时保存 关闭.关闭会自动保存. file.close() 读取全部文件内容用read,读取一行用 ...
- 3.Python编程语言基础技术框架
3.Python编程语言基础技术框架 3.1查看数据项数据类型 type(name) 3.2查看数据项数据id id(name) 3.3对象引用 备注Python将所有数据存为内存对象 Python中 ...
- Python爬虫基础
前言 Python非常适合用来开发网页爬虫,理由如下: 1.抓取网页本身的接口 相比与其他静态编程语言,如java,c#,c++,python抓取网页文档的接口更简洁:相比其他动态脚本语言,如perl ...
- 小白必看Python视频基础教程
Python的排名从去年开始就借助人工智能持续上升,现在它已经成为了第一名.Python的火热,也带动了工程师们的就业热.可能你也想通过学习加入这个炙手可热的行业,可以看看Python视频基础教程,小 ...
- Python爬虫基础之requests
一.随时随地爬取一个网页下来 怎么爬取网页?对网站开发了解的都知道,浏览器访问Url向服务器发送请求,服务器响应浏览器请求并返回一堆HTML信息,其中包括html标签,css样式,js脚本等.我们之前 ...
- 零基础学Python--------第2章 Python语言基础
第2章 Python语言基础 2.1 Python语法特点 2.11注释 在Python中,通常包括3种类型的注释,分别是单行注释.多行注释和中文编码声明注释. 1.单行注释 在Python中,使用 ...
- Python学习基础笔记(全)
换博客了,还是csdn好一些. Python学习基础笔记 1.Python学习-linux下Python3的安装 2.Python学习-数据类型.运算符.条件语句 3.Python学习-循环语句 4. ...
- Python数据分析基础教程
Python数据分析基础教程(第2版)(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1_FsReTBCaL_PzKhM0o6l0g 提取码:nkhw 复制这段内容后 ...
- Python数据分析基础PDF
Python数据分析基础(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1ImzS7Sy8TLlTshxcB8RhdA 提取码:6xeu 复制这段内容后打开百度网盘手 ...
- Python的基础语法(一)
0. 前言 最近正在重新整理Python的基础知识,以便更好地学习新知识.这一部分主要是讲述Python基础语法的演示.下面的语法都是基于Python3的语法. 1. 注释 注释:Python的注释方 ...
随机推荐
- 自己实现java中Iterator(迭代器功能)
今天躺在床上忽然想到一个问题,迭代器的代码是如何实现的?于是乎不由自主的爬起来敲两行代码. List<String> list=new ArrayList<>(2); list ...
- vagrant up 报VirtualBox错误
Debug output $ $ vagrant.exe up ==> default: Checking if box 'janihur/ubuntu-1404-desktop' is up ...
- acm数论之旅(转载)--素数
https://www.cnblogs.com/linyujun/p/5198832.html 前言:好多学ACM的人都在问我数论的知识(其实我本人分不清数学和数论有什么区别,反正以后有关数学的知识我 ...
- 为 git 设定 socks5 代理
为 git 设定 socks5 代理 查看当前设定 git config --global -l 为 git 设定全局代理 git config --global http.proxy socks5h ...
- 【C#】图解如何添加引用using MySql.Data.MySqlClient;
使用C#连接MySQL时,经常会用到命名空间using MySql.Data.MySqlClient; 这说明VS中没有添加引用,解决方法如下: 1,可点击以下两个链接的其中任何一个,下载MySQL. ...
- 用js实现复制内容到操作系统粘贴板(兼容IE、谷歌、火狐等浏览器)
一.如果只考虑IE浏览器,可以直接用原声js实现 if(window.clipboardData){ //清空操作系统粘贴板 window.clipboardData.clearData(); //将 ...
- Java面向对象编程 -1.6
引用传递与垃圾产生分析 经过了一系列的分析之后已经确认,所有的引用传递的本质就是一场堆内存的调戏游戏.如果对于引用传递如果处理不当那么也会造成垃圾的产生, 那么本次将针对于垃圾产生的原因进行简单分析. ...
- VS release模式下进行调试设置
工程项目上右键 打开 属性界面 1.c++ --- 常规 ---- 调试信息格式 选 程序数据库(/Zi)或(/ZI), 注意:如果是库的话,只能(Zi) 2.c/c++ ---- 优化 ---- ...
- redhat7.6 httpd配置php模块
1.安装php yum install "*php*" -y 2.编辑httpd.conf配置文件 找到LoadModule foo_module modules/mod_fo ...
- centos 默认php 版本太低移到高版本的办法
// centos 默认有php 版本太低转移到高版本的解决办法 php -v 版本低 ln -s /usr/local/php/bin/php /usr/bin/php