Python基础知识学习_Day8

一、类的扩展方法

1.静态方法

 语法:@staticmethod,静态方法不能访问公有属性,不能访问类。可在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量。

1 class eat(object):
2     def __init__(self,name):
3         self.name = name
4     @staticmethod #静态方法不能访问共有属性、不能访问实例
5     def eat(name,food):
6         print("%s is eating..%s" %(name,food))
7 p.eat("alex","food")

2.类方法

语法:@classmethod,只能访问类的公有属性,不能访问实例属性。

 1 class Dog(object):
 2     name = "我是类变量"
 3     def __init__(self,name):
 4         self.name = name
 5  
 6     @classmethod
 7     def eat(self):
 8         print("%s is eating" % self.name)
 9  
10  
11  
12 d = Dog("ChenRonghua")
13 d.eat()
14  
15  
16 #执行结果
17  
18 我是类变量 is eating

3.属性方法

语法:@property 把一个方法变成静态属性

 1 class Dog(object):
 2  
 3     def __init__(self,name):
 4         self.name = name
 5  
 6     @property
 7     def eat(self):
 8         print(" %s is eating" %self.name)
 9  
10  
11 d = Dog("ChenRonghua")
12 d.eat

属性方法之航班查询代码

 1 class Flight(object):
 2     def __init__(self,name):
 3         self.flight_name = name
 4 
 5 
 6     def checking_status(self):
 7         print("checking flight %s status " % self.flight_name)
 8         return  1
 9 
10 
11     @property
12     def flight_status(self):
13         status = self.checking_status()
14         if status == 0 :
15             print("flight got canceled...")
16         elif status == 1 :
17             print("flight is arrived...")
18         elif status == 2:
19             print("flight has departured already...")
20         else:
21             print("cannot confirm the flight status...,please check later")
22     
23     @flight_status.setter #修改
24     def flight_status(self,status):
25         status_dic = {
26 : "canceled",
27 :"arrived",
28 : "departured"
29         }
30         print("33[31;1mHas changed the flight status to 33[0m",status_dic.get(status) )
31 
32     @flight_status.deleter  #删除
33     def flight_status(self):
34         print("status got removed...")
35 
36 f = Flight("CA980")
37 f.flight_status
38 f.flight_status =  2 #触发@flight_status.setter 
39 del f.flight_status #触发@flight_status.deleter

4.抽象类

抽象类本身不能被实例化,只能用来被别人继承

上面定义之后,被继承的必须有该方法,也就是上面只定义功能,下面定义实现方法

 1 class AllFile(metaclass=abc.ABCMeta):
 2     @abc.abstractclassmethod
 3     def read(self):
 4         pass
 5     def write(self):
 6         pass
 7 
 8 class Text(AllFile):
 9     def read(self):
10         print('text read')
11     def write(self):
12         print('text write')
13 
14 
15 t = Text()
 1 class Alert(object):
 2     def send(self):
 3         raise NotImplementedError
 4 class MailAlert(Alert):
 5     def send(self,msg):
 6         print("---sending..",msg)
 7 class SMSAlert(Alert):
 8     pass
 9 m = MailAlert()
10 m.send("df")

二.类的特殊成员方法

1.__doc__ 表示类的描述信息

2.__module__表示当前操作的对象在哪个模块

3.__class__ 表示当前操作的对象的类是什么

class C:

    def __init__(self):
        self.name = 'wupeiqi'



from lib.aa import C

obj = C()
print obj.__module__  # 输出 lib.aa,即:输出模块
print obj.__class__      # 输出 lib.aa.C,即:输出类

4.__init__构造方法,通过类创建对象时,自动触发执行。

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

6.__call__ 对象后面加括号,触发执行。

7.__dict__查看类或对象中所有的成员

三.反射

通过字符串映射或修改程序运行的状态、属性、方法。

python中的反射功能是由以下四个内置函数提供:hasattr、getattr、setattr、delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员、获取成员、设置成员、删除成员。

hasattr(容器,'名称')  #以字符串的形式判断某个对象中是否含有指定的属性

getattr(容器,'名称')  #以字符串的形式去某个对象中获取指定的属性

setattr(容器,'名称',值)  #以字符串的形式去某个对象中设置指定的属性

delattr(容器,'名称')  #以字符串的形式去某个对象中删除指定的属性

代码如下:

 1 while True:
 2     inp = input("请输入url>>:")
 3     m,n = inp.split("/")
 4     try:
 5         module = __import__('controller.%s'%m,fromlist = True)
 6         if hasattr(module,n):
 7             func = getattr(module,n)
 8             result = func()
 9     except Exception as e:
10         result = 500
11     print(result)

四.异常处理

在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!!

常见种类:

 1 AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
 2 IOError 输入/输出异常;基本上是无法打开文件
 3 ImportError 无法引入模块或包;基本上是路径问题或名称错误
 4 IndentationError 语法错误(的子类) ;代码没有正确对齐
 5 IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
 6 KeyError 试图访问字典里不存在的键
 7 KeyboardInterrupt Ctrl+C被按下
 8 NameError 使用一个还未被赋予对象的变量
 9 SyntaxError Python代码非法,代码不能编译(个人认为这是语法错误,写错了)
10 TypeError 传入对象类型与要求的不符合
11 UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
12 导致你以为正在访问它
13 ValueError 传入一个调用者不期望的值,即使值的类型是正确的
常见种类
 1 try:
 2     int('add')
 3     li = [11,22]
 4     li[100]
 5 except IndexError as e:  #符合的情况下执行
 6     print("1",e)
 7 except ValueError as e:  #符合的情况下执行
 8     print("2",e)
 9 except Exception as e:  #都能匹配到,以上不满足的情况下,匹配该项。
10     print("3",e)
11 else:
12     print("else")
13 finally:
14     print("finally")  #最后肯定会执行

 五.socket编程

socket本质上就是在2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递。

socket Families 地址簇:socket.AF_INET    #IPV4

socket.SOCK_STREAM    #for tcp

socket.SOCK_DGRAM     #for udp

socket.SOCK_RAM         #原始套接字

socket方法:

socket.socket(family=AF_INETtype=SOCK_STREAMproto=0fileno=None)

 sk.bind(address)  将套接字绑定到地址

sk.listen(backlog)  #开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。

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()

  套接字的文件描述符

代码举例如下:

 1 import socket
 2 import subprocess
 3 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
 4 server.bind(("127.0.0.1",8000))
 5 server.listen(5)
 6 print("-----start to listen------")
 7 while True:
 8     conn,client_addr = server.accept()
 9     print(conn,client_addr)
10     while True:
11         try:
12             data = conn.recv(1024)
13             if not data:
14                 print("客户端已断开")
15                 break
16             print("recv from cli:",data)
17             res_obj = subprocess.Popen(data,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
18             res = res_obj.stdout.read()
19             if len(res) ==0:
20                 cmd_res = "cmd has no output..."
21             conn.send(str(len(res)).encode())
22             print("--res len:",len(res))
23             conn.send(res.encode("utf-8"))
24             print("send done")
25         except Exception as e:
26             print(e)
27 server.close()
 1 import socket
 2 client =socket.socket()
 3 client.connect(("localhost",8000))
 4 while True:
 5     msg = input(">>:").strip()
 6     if len(msg) == 0:continue
 7     client.send(msg.encode("utf-8"))
 8     print("send",msg)
 9     data = client.recv(1024)
10     print("res:",data.decode())
11     total_size=int(data.decode())
12     received_size = 0
13     res = b''
14     while received_size < total_size:
15         d = client.recv(1024)
16         res +=d
17         received_size +=len(d)
18     print("----rece done-----")
19     print(res.decode())
20 client.close()
原文地址:https://www.cnblogs.com/liumj0305/p/6109121.html