python学习笔记_week7

一、面向对象编程进阶

静态方法只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性

 class Dog(object):
def __init__(self,name):
self.name=name
@staticmethod #实际上跟类没什么关系了,调用时用到类名
def eat():
print("s is eating %s"%("dd"))
d=Dog("ChenRonghua")
d.eat()

静态方法

类方法只能访问类变量,不能访问实例变量

 class Dog(object):
#n=333
name="huazai"
def __init__(self,name):
self.name=name
self.n=333
#@staticmethod #实际上跟类没什么关系了,调用时用到类名
@classmethod
def eat(self):
print("%s is eating %s"%(self.name,"dd"))
d=Dog("ChenRonghua")
d.eat()

类方法

属性方法把一个方法变成一个静态属性(隐藏实现细节)

 class Dog(object):
def __init__(self,name):
self.name=name
self.__food=None
#@staticmethod #实际上跟类没什么关系了,调用时用到类名
#@classmethod
@property #attribute
def eat(self):
print("%s is eating %s"%(self.name,self.__food))
@eat.setter #修改
def eat(self,food):
print("set to food:",food)
self.__food=food
@eat.deleter #删除
def eat(self):
del self.__food
print("删完了")
d=Dog("ChenRonghua")
d.eat
d.eat="baozi"
d.eat
del d.eat

属性方法

好吧,把一个方法变成静态属性有什么卵用呢?既然想要静态变量,那直接定义成一个静态变量不就得了么?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 2
@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")
@flight_status.setter
def flight_status(self,status):
print("flight %s has changed status to %s"%(self.flight_name,status)) f = Flight("CA980")
f.flight_status
f.flight_status=0

属性方法例子

(一)、类的特殊成员方法

1. __doc__  表示类的描述信息

 class Foo:
""" 描述类信息 """
def func(self):
pass
print(Foo.__doc__)# 输出:描述类信息

2. __module__ 和  __class__ 

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

aa

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

index

python学习笔记_week7

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

4.__del__

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

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

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

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

 class Foo:
def __init__(self):
pass def __call__(self, *args, **kwargs):
print('__call__',args,kwargs) obj = Foo() # 执行 __init__
obj(1,2,3,name=333) # 执行 __call__

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

 class Dog(object):
def __init__(self,name):
self.name=name
self.__food=None
#@staticmethod #实际上跟类没什么关系了,调用时用到类名
#@classmethod
@property #attribute
def eat(self):
print("%s is eating %s"%(self.name,self.__food))
@eat.setter #修改
def eat(self,food):
print("set to food:",food)
self.__food=food
@eat.deleter #删除
def eat(self):
del self.__food
print("删完了")
print(WindowsError.__dict__)#打印类里的所有属性,不包括实例属性
d=Dog("ChenRonghua")
print(d.__dict__)#打印所有实例属性,不包括类属性

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

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

8.__getitem__、__setitem__、__delitem__

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

 class Foo(object):
def __init__(self):
self.data={}
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)
obj = Foo()
obj["name"]="alex"# 自动触发执行 __setitem__
print(obj["name"]) # 自动触发执行 __getitem__
print(obj.data)
del obj["name"] #不是真正的删除
print(obj["name"])

9. __new__ \ __metaclass__

 # class Foo(object):
# def __init__(self, name):
# self.name = name
# f = Foo("alex")
# print(type(f))
# print(type(Foo)) #来自于type def func(self):
print('hello %s'%self.name)
def __init__(self,name,age):
self.name=name
self.age=age
Foo = type('Foo',(object,),{'func':func,"__init__":__init__})#boject,表示元组 # type第一个参数:类名
# type第二个参数:当前类的基类
# type第三个参数:类的成员
f=Foo("chrn",22)
f.func()
print(type(Foo))

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

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

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

那么,创建类就可以有两种方式:普通方式和特殊方式

So ,孩子记住,类 是由 type 类实例化产生

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

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

python学习笔记_week7python学习笔记_week7

 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 obj
def __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 = name
print("Foo __init__")
def __new__(cls, *args, **kwargs):
print("Foo __new__",cls, *args, **kwargs)
return object.__new__(cls) #继承父类的__new__方法
f = Foo("Alex")
print("f",f)
print("fname",f.name)

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

metaclass 详解文章:http://*.com/questions/100003/what-is-a-metaclass-in-python 得票最高那个答案写的非常好

(二)、反射

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

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

  setattr(obj,"y",z), is equivalent to ``obj.y = v''

  delattr(obj,"y") ,is equivalent to ``del obj.y''

 def bulk(self):
print("%s is yelling..."%self.name)
class Dog(object):
def __init__(self,name):
self.name=name
def eat(self,food):
print("%s is eating %s"%(self.name,food)) d=Dog("NiuHanYang")
choice=input(">>:").strip()
# print(hasattr(d,choice))
# print(getattr(d,choice))
if hasattr(d,choice): #func=getattr(d,choice)
#func("chenronghua") # attr=getattr(d,choice)#没有也一样
# setattr(d,choice,"Ronghua") delattr(d.choice)
else:
setattr(d,choice,bulk) #d.talk=bulk
func=getattr(d,choice)
func(d)
# setattr(d,choice,22)
# print(getattr(d,choice))
print(d.name)

(三)、异常处理

1、异常基础

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

try:

  code

except (Error1,Error2) as e:

  print(e)

except Exception:抓住所有错误,不建议一开始就用

 names=['alex',"jack"]
data={}
try:
open("tes.txt")
# a=1
# print(a)
except (KeyError,IndexError) as e:
print("没有这个key",e) #e就是错误的详细信息
except Exception as e:
print("未知错误",e)
else: #没有错误,执行这个
print("一切正常")
finally:
print("不管有没有错,都执行")

2、异常种类

python中的异常种类非常多,每个异常专门用于处理某一项异常!!!

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

常用异常

万能异常 在python的异常中,有一个万能异常:Exception,他可以捕获任意异常。

接下来你可能要问了,既然有这个万能异常,其他异常是不是就可以忽略了!

答:当然不是,对于特殊处理或提醒的异常需要先定义,最后定义Exception来确保程序正常运行。

 s1 = 'hello'
try:
int(s1)
except KeyError,e:
print '键错误'
except IndexError,e:
print '索引错误'
except Exception, e:
print '错误'

3、异常其他结构

 try:
# 主代码块
pass
except KeyError,e:
# 异常时,执行该块
pass
else:
# 主代码块执行完,执行该块
pass
finally:
# 无论异常与否,最终执行该块
pass

4、主动触发异常

try:
raise Exception('错误了。。。')
except Exception as e:
print (e)

5、自定义异常

 class AlexException(Exception):
def __init__(self, msg):
self.message = msg
# def __str__(self):
# return "sfadad"
try:
raise AlexException('数据库连不上') #触发异常
except AlexException as e:
print(e)

6、断言

 # assert 条件

 assert 1 == 1

 assert 1 == 2

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

二、Socket 编程

python学习笔记_week7python学习笔记_week7

协议类型就叫地址簇

进程之间默认不可通信

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头。(伪造ip地址,洪水攻击)

socket.SOCK_RDM  #是一种可靠的UDP形式,即保证交付数据报但不保证顺序。SOCK_RAM用来提供对原始协议的低级访问,在需要执行某些特殊操作时使用,如发送ICMP报文。SOCK_RAM通常仅限于高级用户或管理员运行的程序使用。

socket.SOCK_SEQPACKET #废弃了

客户端

 #客户端
import socket
client=socket.socket() #声明socket类型,同时生成socket连接对象
client.connect(("localhost",6969))
client.send("我的a".encode("utf-8"))
data=client.recv(1024)
print("recv:",data.decode())
client.close()

服务器端

 #服务器端
import socket
server=socket.socket()
server.bind(("localhost",6969)) #绑定要监听的端口
server.listen() #监听
print("我要开始等电话了")
conn,addr=server.accept() #等电话打进来
#conn就是客户端连过来而在服务器端为其生成的一个连接实例
print(conn,addr) print("电话来了")
data=conn.recv(1024)
print("recv:",data)
conn.send(data.upper()) server.close()

多用户客户端

 #客户端
import socket
client=socket.socket() #声明socket类型,同时生成socket连接对象
client.connect(("localhost",6969)) while True:
msg=input(">>:").strip()
if len(msg)==0:
continue
client.send(msg.encode("utf-8"))#如果没有上面的if,不能send"空",会卡住
data=client.recv(1024)#recv大小有限制
print("recv:",data.decode())
client.close()

多用户客户端

多用户服务器端

 #服务器端
import os
import socket
server=socket.socket()
server.bind(("localhost",6969)) #绑定要监听的端口
server.listen(5) #监听,最多可以挂起..个链接(排队)
print("我要开始等电话了")
while True:
conn,addr = server.accept() # 等电话打进来
# conn就是客户端连过来而在服务器端为其生成的一个连接实例
print(conn, addr)
print("电话来了")
while True:
data=conn.recv(1024)#服务器端接收的大小也有限制
print("recv:",data)
if not data:
print("client has lost")
break
res=os.popen(data).read
conn.send(res)#conn.sendall(data)循环send,send大小也有限制(缓冲区的大小),与系统有关
server.close()

多用户服务器端

windows中不好使...

python学习笔记_week7python学习笔记_week7

python学习笔记_week7

socket概念

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

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

python学习笔记_week7

上一篇:Oracle 12C RAC的optimizer_adaptive_features造成数据插入超时


下一篇:C语言第七次博客作业--一二维数组