python学习笔记_week7

一、面向对象编程进阶

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

1 class Dog(object):
2     def __init__(self,name):
3         self.name=name
4     @staticmethod #实际上跟类没什么关系了,调用时用到类名
5     def eat():
6         print("s is eating %s"%("dd"))
7 d=Dog("ChenRonghua")
8 d.eat()
静态方法

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

 1 class Dog(object):
 2     #n=333
 3     name="huazai"
 4     def __init__(self,name):
 5         self.name=name
 6         self.n=333
 7     #@staticmethod #实际上跟类没什么关系了,调用时用到类名
 8     @classmethod
 9     def eat(self):
10         print("%s is eating %s"%(self.name,"dd"))
11 d=Dog("ChenRonghua")
12 d.eat()
类方法

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

 1 class Dog(object):
 2     def __init__(self,name):
 3         self.name=name
 4         self.__food=None
 5     #@staticmethod #实际上跟类没什么关系了,调用时用到类名
 6     #@classmethod
 7     @property #attribute
 8     def eat(self):
 9         print("%s is eating %s"%(self.name,self.__food))
10     @eat.setter #修改
11     def eat(self,food):
12         print("set to food:",food)
13         self.__food=food
14     @eat.deleter #删除
15     def eat(self):
16         del self.__food
17         print("删完了")
18 d=Dog("ChenRonghua")
19 d.eat
20 d.eat="baozi"
21 d.eat
22 del d.eat
属性方法

好吧,把一个方法变成静态属性有什么卵用呢?既然想要静态变量,那直接定义成一个静态变量不就得了么?well, 以后你会需到很多场景是不能简单通过 定义 静态属性来实现的, 比如 ,你想知道一个航班当前的状态,是到达了、延迟了、取消了、还是已经飞走了, 想知道这种状态你必须经历以下几步:

1. 连接航空公司API查询

2. 对查询结果进行解析 

3. 返回结果给你的用户

因此这个status属性的值是一系列动作后才得到的结果,所以你每次调用时,其实它都要经过一系列的动作才返回你结果,但这些动作过程不需要用户关心, 用户只需要调用这个属性就可以,明白 了么?

 1 class Flight(object):
 2     def __init__(self,name):
 3         self.flight_name = name
 4     def checking_status(self):
 5         print("checking flight %s status " % self.flight_name)
 6         return  2
 7     @property
 8     def flight_status(self):
 9         status = self.checking_status()
10         if status == 0 :
11             print("flight got canceled...")
12         elif status == 1 :
13             print("flight is arrived...")
14         elif status == 2:
15             print("flight has departured already...")
16         else:
17             print("cannot confirm the flight status...,please check later")
18     @flight_status.setter
19     def flight_status(self,status):
20         print("flight %s has changed status to %s"%(self.flight_name,status))
21 
22 
23 f = Flight("CA980")
24 f.flight_status
25 f.flight_status=0
属性方法例子

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

1. __doc__  表示类的描述信息
1 class Foo:
2     """ 描述类信息 """
3     def func(self):
4         pass
5 print(Foo.__doc__)# 输出:描述类信息
View Code
2. __module__ 和  __class__ 
1 class C:
2     def __init__(self):
3         self.name = 'wupeiqi'
aa
1 from lib.aa import C
2 obj = C()
3 print( obj.__module__)  # 输出 lib.aa,即:输出模块
4 print(obj.__class__)      # 输出 lib.aa.C,即:输出类
index

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

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

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

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

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

1 class Foo:
2     def __init__(self):
3         pass
4 
5     def __call__(self, *args, **kwargs):
6         print('__call__',args,kwargs)
7 
8 obj = Foo()  # 执行 __init__
9 obj(1,2,3,name=333)  # 执行 __call__
View Code
6. __dict__ 查看类或对象中的所有成员
 1 class Dog(object):
 2     def __init__(self,name):
 3         self.name=name
 4         self.__food=None
 5     #@staticmethod #实际上跟类没什么关系了,调用时用到类名
 6     #@classmethod
 7     @property #attribute
 8     def eat(self):
 9         print("%s is eating %s"%(self.name,self.__food))
10     @eat.setter #修改
11     def eat(self,food):
12         print("set to food:",food)
13         self.__food=food
14     @eat.deleter #删除
15     def eat(self):
16         del self.__food
17         print("删完了")
18 print(WindowsError.__dict__)#打印类里的所有属性,不包括实例属性
19 d=Dog("ChenRonghua")
20 print(d.__dict__)#打印所有实例属性,不包括类属性
View Code
7.__str__ 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。
1 class Foo:
2     def __str__(self):
3         return 'alex li'
4 obj = Foo()
5 print(obj)
6 # 输出:alex li
View Code
8.__getitem__、__setitem__、__delitem__

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

 1 class Foo(object):
 2     def __init__(self):
 3         self.data={}
 4     def __getitem__(self, key):
 5         print('__getitem__', key)
 6         return self.data.get(key)
 7     def __setitem__(self, key, value):
 8         print('__setitem__', key, value)
 9         self.data[key]=value
10     def __delitem__(self, key):
11         print('__delitem__', key)
12 obj = Foo()
13 obj["name"]="alex"# 自动触发执行 __setitem__
14 print(obj["name"]) # 自动触发执行 __getitem__
15 print(obj.data)
16 del obj["name"] #不是真正的删除
17 print(obj["name"])
View Code
9. __new__ \ __metaclass__
 1 # class Foo(object):
 2 #     def __init__(self, name):
 3 #         self.name = name
 4 # f = Foo("alex")
 5 # print(type(f))
 6 # print(type(Foo)) #来自于type
 7 
 8 
 9 def func(self):
10     print('hello %s'%self.name)
11 def __init__(self,name,age):
12     self.name=name
13     self.age=age
14 Foo = type('Foo',(object,),{'func':func,"__init__":__init__})#boject,表示元组
15 
16 # type第一个参数:类名
17 # type第二个参数:当前类的基类
18 # type第三个参数:类的成员
19 f=Foo("chrn",22)
20 f.func()
21 print(type(Foo))
View Code

 

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

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

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

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

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

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

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

 1 class MyType(type):
 2     def __init__(self,*args,**kwargs):
 3         print("Mytype __init__",*args,**kwargs)
 4     def __call__(self, *args, **kwargs):
 5         print("Mytype __call__", *args, **kwargs)
 6         obj = self.__new__(self)
 7         print("obj ",obj,*args, **kwargs)
 8         print(self)
 9         self.__init__(obj,*args, **kwargs)
10         return obj
11     def __new__(cls, *args, **kwargs):
12         print("Mytype __new__",*args,**kwargs)
13         return type.__new__(cls, *args, **kwargs)
14 print('here...')
15 class Foo(object,metaclass=MyType):
16     def __init__(self,name):
17         self.name = name
18         print("Foo __init__")
19     def __new__(cls, *args, **kwargs):
20         print("Foo __new__",cls, *args, **kwargs)
21         return object.__new__(cls) #继承父类的__new__方法
22 f = Foo("Alex")
23 print("f",f)
24 print("fname",f.name)
View Code

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

 metaclass 详解文章:http://stackoverflow.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''

 1 def bulk(self):
 2     print("%s is yelling..."%self.name)
 3 class Dog(object):
 4     def __init__(self,name):
 5         self.name=name
 6     def eat(self,food):
 7         print("%s is eating %s"%(self.name,food))
 8 
 9 d=Dog("NiuHanYang")
10 choice=input(">>:").strip()
11 # print(hasattr(d,choice))
12 # print(getattr(d,choice))
13 if hasattr(d,choice):
14 
15     #func=getattr(d,choice)
16     #func("chenronghua")
17 
18     # attr=getattr(d,choice)#没有也一样
19     # setattr(d,choice,"Ronghua")
20 
21     delattr(d.choice)
22 else:
23     setattr(d,choice,bulk) #d.talk=bulk
24     func=getattr(d,choice)
25     func(d)
26     # setattr(d,choice,22)
27     # print(getattr(d,choice))
28 print(d.name)
View Code

(三)、异常处理

1、异常基础

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

try:

  code

except (Error1,Error2) as e:

  print(e)

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

 1 names=['alex',"jack"]
 2 data={}
 3 try:
 4     open("tes.txt")
 5     # a=1
 6     # print(a)
 7 except (KeyError,IndexError) as e:
 8     print("没有这个key",e) #e就是错误的详细信息
 9 except Exception as e:
10     print("未知错误",e)
11 else: #没有错误,执行这个
12     print("一切正常")
13 finally:
14     print("不管有没有错,都执行")
View Code

2、异常种类

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

 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 传入一个调用者不期望的值,即使值的类型是正确的
常用异常

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

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

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

1 s1 = 'hello'
2 try:
3     int(s1)
4 except KeyError,e:
5     print '键错误'
6 except IndexError,e:
7     print '索引错误'
8 except Exception, e:
9     print '错误'
View Code

3、异常其他结构

 1 try:
 2     # 主代码块
 3     pass
 4 except KeyError,e:
 5     # 异常时,执行该块
 6     pass
 7 else:
 8     # 主代码块执行完,执行该块
 9     pass
10 finally:
11     # 无论异常与否,最终执行该块
12     pass
View Code

4、主动触发异常

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

5、自定义异常

1 class AlexException(Exception):
2     def __init__(self, msg):
3         self.message = msg
4     # def __str__(self):
5     #     return "sfadad"
6 try:
7     raise AlexException('数据库连不上') #触发异常
8 except AlexException as e:
9     print(e)
View Code

6、断言

1 # assert 条件
2  
3 assert 1 == 1
4  
5 assert 1 == 2
View Code

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

二、Socket 编程

协议类型就叫地址簇

进程之间默认不可通信

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 #废弃了

客户端

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

服务器端

 1 #服务器端
 2 import socket
 3 server=socket.socket()
 4 server.bind(("localhost",6969)) #绑定要监听的端口
 5 server.listen() #监听
 6 print("我要开始等电话了")
 7 conn,addr=server.accept() #等电话打进来
 8 #conn就是客户端连过来而在服务器端为其生成的一个连接实例
 9 print(conn,addr)
10 
11 print("电话来了")
12 data=conn.recv(1024)
13 print("recv:",data)
14 conn.send(data.upper())
15 
16 server.close()
View Code

多用户客户端

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

多用户服务器端

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

windows中不好使...

socket概念

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

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

 

posted on 2017-10-30 11:09  我很好u 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/jyh-py-blog/p/7753637.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值