python学习笔记7

类的方法进阶:

    静态方法:在类的方法前面加上装饰器@staticmethod,类的内置方法变为静态方法。变为静态方法后,下面的方法变成了函数,需要传入参数self,与类关系不大。示例如下:

 1 class Dog(object):
 2     def __init__(self,name):
 3         self.name=name
 4 
 5     @staticmethod#变为静态方法后,下面的方法变成了函数,需要传入参数self,与类关系不大
 6     def eat(self,food):
 7         print('%s is eating %s'%(self.name,food))
 8 d1=Dog('wangcai')
 9 d2=Dog('shamo')
10 d1.eat(self=d1,food='chicken')#调用形式和类差不多,self需要传参数
11 d1.eat(d2,'gourou')

    类方法:在类的方法前面加上装饰器@classmethod,类的内置方法变为类方法。类方法,只能访问类变量,无法访问实例变量,self=类名Dog。示例如下:

#类方法:只能访问类变量,不能访问实例变量
class Dog(object):
    name='哈士奇'
    def __init__(self,name):
        self.name=name

    @classmethod#类方法,只能访问类变量,无法访问实例变量,self=类名Dog
    def eat(self,food):
        print('%s is eating %s'%(self.name,food))
d1=Dog('wangcai')
d2=Dog('shamo')
d2.eat('chicken')
d1.eat('gourou')

    属性方法:在类的方法前加上装饰器@property,将类的方法变为一个静态属性。属性方法把一个方法变成静态属性,隐藏实现细节,不能调用,不能传入参数。传入参数,需要添加一个带装饰器@静态属性名.setter的方法,此时给静态属性赋值,相当于传参。示例如下:

#属性方法:把一个方法变成静态属性,隐藏实现细节
class Dog(object):
    name='哈士奇'
    def __init__(self,name):
        self.name=name
        self.__food=None
        self.__character=None
    @property#属性方法,此时.eat作为一个变量,但不能赋值,也不能传参数
    def eat(self):
        print("%s is eating %s."%(self.name,self.__food))
    @eat.setter#此时可以传入一个参数,可通过给属性赋值
    def Eat(self,food):
        print('set food to:%s'%food)
        self.__food=food
    @eat.deleter
    def EAT(self):
        del self.__food
        print('You have deleted "eat".')

d1=Dog('wangcai')
d2=Dog('shamo')
#d1.eat(food='rou')
#d2.eat(food='chicken')
#d1.eat(food='gourou')
d1.eat
d1.Eat=d2.name#调用属性eat,传入参数d2.name
d1.eat
#删除属性方法定义的属性,默认无法删除
#del d1.EAT#没有定义@eat.deleter时会报错,定义后可以删除
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("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")


f = Flight("CA980")
f.flight_status

    __mateclass__方法:其用来表示该类由谁来实例化创建。

        类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__

        def __new__(cls, *args, **kwargs),会在类实例化的时候自动执行,执行顺序在__init__()之前,是用来创建实例的

class MyType(type):
      def __init__(self,*args,**kwargs):

         print("Mytype __init__",*args,**kwargs)

      def __call__(self, *args, **kwargs):#通过call创建new
         print("Mytype __call__", *args, **kwargs)
         obj = self.__new__(self)
         print("obj ",obj,*args, **kwargs)
         print(self)
         self.__init__(obj,*args, **kwargs)
         return obj

      def __new__(cls, *args, **kwargs):
          print("Mytype __new__",*args,**kwargs)
          return type.__new__(cls, *args, **kwargs)

print('here...')
class Foo(object,metaclass=MyType):
#class Foo(object):
     #__metatype__=MyType
     def __init__(self,name):
         self.name = name

         print("Foo __init__")

     def __new__(cls, *args, **kwargs):#不写默认继承object.__new__,写了就会重构
         print("Foo __new__",cls, *args, **kwargs)
         return object.__new__(cls)#缺少这一句构造函数不会执行,通过__new__来实例化,new调用init。
        #return调用父类的new方法,cls传递一个类

f = Foo("Alex")
# print("f",f)
# print("fname",f.name)

    类的定义方式:分为普通定义方式和特殊定义方式。

#创建类的方式
#普通方式定义类
class Foo(object):
    def __init__(self,name):
        self.name=name

f=Foo('wulihuang')
#特殊方式定义类
def func(self,number):
    print('hehe',self.name,self.age)
    print('number:%s'%number)
def __init__(self,name,age):
    self.name=name
    self.age=age
Foo1=type('Foo1',(object,),{'hello':func,
                            '__init__':__init__})#type为类的类
#type的三个参数,第一个为类名,第二个为类的基类,第三个为类的成员,可以加入构造函数等
f1=Foo1('diaocan',18)
f1.hello(15)

    类的字典操作:

#__getitem__获取数据
# __setitem__设置数据
# __delitem__删除数据
class Foo(object):
    def __init__(self):
        self.data={'k1':'zhaoyu'}
    def __getitem__(self, key):
        print('__getitem__', key)
        return self.data.get(key)
    def __setitem__(self, key, value):
        print('__setitem__', key, value)
        self.data[key]=value
    def __delitem__(self, key):
        print('__delitem__', key)
        del self.data[key]

obj = Foo()

print(obj['k1'])  # 自动触发执行 __getitem__
obj['k2'] = 'alex'  # 自动触发执行 __setitem__
print(obj.data)
del obj['k1']
print(obj.data)

反射:

  通过字符串映射或修改程序运行时的状态、属性、方法, 实现动态的内存装配,有以下4个方法:

    hasattr(obj, name, /) 判断一个对象里是否有叫’name‘的属性或方法。

    getattr(object, name[, default]) -> value 从对象获取命名属性; getattr(x,'y')相当于x.y,如果给出了默认参数,则在属性不存在时返回它; 没有它,在这种情况下会引发Exception。

    setattr(obj, name, value, /), 将给定对象的命名属性设置为指定值,setattr(x,'y',v)相当于``x.y = v''

    delattr(x,'y')从对象x里删除属性,相当于del x.y

#反射:通过字符串映射或修改程序运行时的状态、属性、方法, 实现动态的内存装配,有以下4个方法
#hasattr(obj, name, /) 判断一个对象里是否有叫’name‘的属性或方法。
#getattr(object, name[, default]) -> value 从对象获取命名属性; getattr(x,'y')相当于x.y,如果给出了默认参数,\
# 则在属性不存在时返回它; 没有它,在这种情况下会引发Exception。
#setattr(obj, name, value, /), 将给定对象的命名属性设置为指定值,setattr(x,'y',v)相当于``x.y = v''
#delattr(x,'y')从对象x里删除属性,相当于del x.y          。
def burk(self):
    print('%s is barking'%self.name)
class Dog(object):
    def __init__(self,name,sex):
        self.name=name
        self.sex=sex
    def eat(self,food):
        print('%s is eating %s'%(self.name,food))
d1=Dog('wangcai','M')
choice=input('>>:').strip()
print(hasattr(d1,choice))#判断d1中是否有属性或方法choice
print(getattr(d1,choice,'noexist'))#打印的d1.choice内存地址,不存在时返回noexist
if hasattr(d1,choice):
    getattr(d1,choice)('gutou')
else:
    setattr(d1,choice,burk)
    getattr(d1,choice)(d1)#需要传入参数self
# delattr(d1,choice)
# print(d1.name)

异常处理:

    异常处理作用:在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!!

    常用的异常:    

      AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
      IOError 输入/输出异常
      FileNotFoundError 找不到文件
      ImportError 无法引入模块或包;基本上是路径问题或名称错误
      IndentationError 语法错误(的子类) ;代码没有正确对齐
      IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
      KeyError 试图访问字典里不存在的键
      KeyboardInterrupt Ctrl+C被按下
      NameError 使用一个还未被赋予对象的变量
      SyntaxError Python代码非法,代码不能编译
      TypeError 传入对象类型与要求的不符合
      UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
    导致你以为正在访问它
      ValueError 传入一个调用者不期望的值,即使值的类型是正确的

    示例:

#异常处理作用:
    #在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!!
#示例
list1=['zhaoyu','nvbu','wusong']
dict1={}
try:#出现第一个异常后便执行except,后面的异常无法判断
     dict1['name']
     list1[6]
     open('hheh.txt', 'r', encoding='uft-8')
except IndexError as e:#except (IndexError,KeyError) as e:同时判断两种异常
    print('列表序号错误,超出最大序号',e)
except KeyError as e:#可以写多次
    print('这个key %s 不存在'%e)
except Exception as e:#能抓住大部分错误,但是无法定位错误
    print('未知错误',e)
else:#没出错的时候执行
    print('一切正常')
finally:
    print('finally 不管有没有错都执行')

#常用的异常
# AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
# IOError 输入/输出异常
#FileNotFoundError  找不到文件
# ImportError 无法引入模块或包;基本上是路径问题或名称错误
# IndentationError 语法错误(的子类) ;代码没有正确对齐
# IndexError 下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
# KeyError 试图访问字典里不存在的键
# KeyboardInterrupt Ctrl+C被按下
# NameError 使用一个还未被赋予对象的变量
# SyntaxError Python代码非法,代码不能编译
# TypeError 传入对象类型与要求的不符合
# UnboundLocalError 试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,
# 导致你以为正在访问它
# ValueError 传入一个调用者不期望的值,即使值的类型是正确的
#自定义异常
class UserDifinedException(Exception):#自定义异常类,继承Exception
    def __init__(self, msg):
        self.message = msg
    def __str__(self):#继承了Exception,可以不重构__str__
        return self.message
try:
    raise UserDifinedException('自定义异常')#主动触发,raise触发
except UserDifinedException as e:
    print(e)

动态导入模块:

动态导入模块方法1: __import__

说明:

  1. 函数功能用于动态的导入模块,主要用于反射或者延迟加载模块。

  2. __import__(module)相当于import module

举例说明:

首先创建一个模块目录lib,然后在目录内创建一个模块为:aa.py

模块代码为:

class c(object):
    def __str__(self):
        return 'C language'
在lib目录平级新建一个测试的模块,使用 __import__ 动态以字符串形式导入lib下的aa模块。

lib = __import__('lib.aa') # 相当于import lib
c = lib.aa.c()
print(c)
动态导入模块方法2:import importlib

实例还是上面的lib.aa模块,这里使用importlib进行动态导入(这个方法好理解,也是官方建议使用的)

import importlib
aa = importlib.import_module('lib.aa')
c = aa.c()
print(c)

Socket网络编程:

网络协议:http网站,smtp email,dns把域名解析成IP地址,ftp下载上传文件,ssh,snmp简单网络通信协议,
icmp ping包测试网路通不通,dhcp IP地址分配
数据通信:通过通信协议进行发和收,send和receive,数据流交换
OSI(Open System Interconnection)七层模型:从上到下如下
应用层:网络服务与最终用户的一个接口,协议有:HTTP FTP TFTP SMTP SNMP DNS。
表示层:数据的表示、安全、压缩。(在五层模型里面已经合并到了应用层),格式有,JPEG、ASCll、DECOIC、加密格式等。
会话层:建立、管理、终止会话。(在五层模型里面已经合并到了应用层)。对应主机进程,指本地主机与远程主机正在进行的会话。
传输层:定义传输数据的协议端口号,以及流控和差错效验。协议有:TCP和UDP,数据包一旦离开网卡即进入网络传输层。
网络层:进行逻辑地址寻址,实现不同网络之间的路径选择。协议有:ICMP IGMP IP(IPV4 IPV6) ARP RARP(地址簇)。识别IP地址,
数据链路层 (Link):建立逻辑连接、进行硬件地址寻址、差错效验等功能。(由底层网络定义协议)。\
将比特组合成字节进而组合成帧,用MAC地址访问介质,错误发现但不能纠正。不认识IP地址。MAC地址:物理地址,16进制
物理层(Physical Layer):建立、维护、断开物理连接。(由底层网络定义协议)。
TCP/IP通信:三次握手,四次断开
TCP/IP连接
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,\
此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,\
客户端和服务器进入ESTABLISHED状态,完成三次握手。
TCP/IP断开
1、建立连接后,任意一方调用close()函数后,向对方发生FIN=M数据包,进入FIN_WAIT_1状态。FIN(finish缩写)
2、被动关闭端收到FIN数据包后,检测到设置了FIN标志位,发送一个ACK=M+1给主动关闭端,被动端进入CLOSE_WAIT状态。
3、被动端发送一个FIN=k数据包给主动端,被动端进入FIN_WAIT_2状态。
4、主动断开端收到被动端的FIN数据包,进入TIME_WAIT状态,发生一个ACK=k+1给被动端,被动端进入CLOSE状态。
UDP协议:
UDP协议并不提供数据传送的保证机制。如果在从发送方到接收方的传递过程中出现数据报的丢失,/
协议本身并不能做出任何检测或提示。因此,通常人们把UDP协议称为不可靠的传输协议。UDP具有TCP所望尘莫及的速度优势。
socket:将数据的send、receive等数据流交换进行封装,调用的接口。
一台机器:总共开放的port数为65535。Nginx(网站)默认为port80,Mysql默认为3306
IP地址:定位计算机
port:定位计算机上的程序
实现通信,需要IP加端口port
Socket Families(地址簇)
socket.AF_UNIX unix本机进程间通信
socket.AF_INET IPV4 
socket.AF_INET6 IPV6
Socket Types
socket.SOCK_STREAM #for tcp
socket.SOCK_DGRAM #for udp
socket.SOCK_RAW #原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;\
其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
socket.SOCK_RDM #是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,\
在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。
  示例:
#socket客户端
import socket
#socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)#第一参数为数据簇,默认为IPV4,第二个为协议类型,默认为TCP
client=socket.socket()#定义数据簇和协议类型,socket在socket.py里是一个类,进行实例化
client.connect(('localhost',8002))#只能接受一个参数,需要IP地址和端口号1,所以以元组形式传入,连接服务器端
#client.send(data,flags=None)向服务端传输data,data必须为字符串型
client.send(b'hello world!')#向服务器端传输数据字符串‘hello world!’,python3里发送类型必须为bytes。
client.send('吴礼辉'.encode('utf-8'))#中文转化为bytes类型
n=1
while n<2:
    msg=input('>>:').strip()
    if len(msg)==0:continue
    client.send(msg.encode('utf-8'))
    #bytes只能转化ASCLL的数据类型
    #client.recv(buffersize,flags=None)接受来自服务器端的数据,buffersize定义接受字节的数量
    data=client.recv(1024000000)#最多接收1024个字节(1kb),超过的部分留在缓冲区排队,下次继续接收
    print('recv: ',data.decode())
    if msg=='q':
        n=2
client.close()
#socket 服务器端
import socket
server=socket.socket()#定义数据簇和协议类型,socket在socket.py里是一个类,进行实例化
#server.bind(address)捆绑socket到固定地址,对于IP sockets,地址是数据对(host,port)
server.bind(('localhost',8002))#绑定要监听的端口
#server.listen(backlog=None)#使服务器接受连接,不自定义backlog会自动选择合适的值
server.listen(5)#监听,5表示最大允许5个连接挂起
print('等待连接')
while True:#一个客户端断开后,等待另一个客户端连接
    #server.accept()等待传入连接。 return正在连接的新socket实例以及客户端的address。 对于IP套接字,地址信息是一对(hostaddr,端口)。
    conn,addr=server.accept()#等待连接
    #conn是客户端连接过来后,服务器端为其生成的连接实例
    print(conn,'\r\n',addr)
    print('连接成功')
    while True:#实现客户端与服务端的多个数据交互
        data=conn.recv(10240000)#不选择server.recv(),这样可以同时连入多个客户端
        print('server recv:',data.decode())
        if not data:
            print('客户端连接失败')
            break
        conn.send(data.upper())
server.close()

猜你喜欢

转载自www.cnblogs.com/wulihui/p/9374453.html
今日推荐