day7—直播内容(元昊老师著)

    
*******************************
class animal(object):
def __init__(self):
self.is_handsome=True

def eat(self):
if self.is_handsome:
print "eat...."
else:
print "no handsome"

class dog(animal):
def __init__(self):
#animal.__init__(self)
super(dog,self).__init__()
self.hair="black"

def bite(self):
print "bite me!"

d=dog()
d.bite()
d.eat()

******************************************



我有一个字典,从某个地方获取的,比如http请求发过来的,我要根据这个
字典来构建一个对象。

class Person:
def __init__(self,_obj):
self.name = _obj['name']
self.age = _obj['age']
self.energy = _obj['energy']
self.gender = _obj['gender']
self.email = _obj['email']
self.phone = _obj['phone']
self.country = _obj['country']

class Person:
def __init__(self,_obj):
self.__dict__.update(_obj)


在Python中,所有的东西都是对象,这些对象是由一个类型实例化而来;那么说,
这些对象就有属性和方法,属性可以存储一些值。而从直观上来看,任何可以存储
东西的事物,我们都可以说它有一个空间(只有有空间,才能存储东西嘛),而在
编程中,我们一般使用术语“名字空间”或“命名空间”(namespace)来称呼它。这样,
我们就得出,每个对象都有一个名字空间。而在Python中,我们使用对象的__dict__
属性来保存该对象的名字空间中的东西,__dict__是一个字典(“键-值”对,一般“键”
就是属性名或方法名,“值”就是属性的值或方法名所指向的真正的方法实体对象)。

#__dict__:实例属性
class Animal:
price = 10
__a = 22
def __init__(self):
self.__color = "red"
self.__price = 11

class Dog(Animal):
__b = 10
c = 33

if __name__ == "__main__":
dog=Dog()
print (dog.__dict__)

*******************************************
在Python中,重载__getattr__、__setattr__、__delattr__和__getattribute__
方法可以用来管理一个自定义类中的属性访问。其中,__getattr__方法将拦截所
有未定义的属性获取(即,当要访问的属性已经定义时,该方法不会被调用,至于
定义不定义,是由Python能否查找到该属性来决定的);__getattribute__方法将
拦截所有属性的获取(不管该属性是否已经定义,只要获取它的值,该方法都会调
用),由于此情况,所以,当一个类中同时重载了__getattr__和__getattribute__
方法,那么__getattr__永远不会被调用,另外,__getattribute__方法仅仅存在于
Python2.6的新式类和Python3的所有类中;__setattr__方法将拦截所有的属性赋
值;__delattr__方法将拦截所有的属性删除。说明:在Python中,一个类或类实
例中的属性是动态的(因为Python是动态的),也就是说,你可以往一个类或类实
例中添加或删除一个属性。


1.1 重载__setattr__方法:
在重载__setattr__方法时,不能使用“self.name = value”格式,否则,它将会导致
递归调用而陷入死循环。正确的应该是:

def __setattr__(self, name, value):
# do-something
object.__setattr__(self, name, value)
# do-something

注:其中的“object.__setattr__(self, name, value)”一句可以换成
“self.__dict__[name] = value”;

1.2 重载__delattr__方法:
在重载__delattr__方法时,不能使用del self.name格式,否则,它将会导致递归
调用而陷入死循环。正确的应该是:

def __delattr__(self, name):
# do-something
object.__delattr__(self, name)
# do-something

注:其中的“object.__delattr__(self, name)”一句可以换成
“del self.__dict__[name]”;

1.3 重载__getattribute__方法:

def __getattribute__(self, name):
# do-something
return object.__getattribute__(self, name)
# do-something
在__getattribute__方法中不能把“return object.__getattribute__(self, name)
”一句替换成“return self.__dict__[name]”来避免循环,因为它
(即其中的self.__dict__)也会触发属性获取,进而还是会导致递归调用。

1.4 重载__getattr__方法:
由于__getattr__方法是拦截未定义的属性,所以它没有其他三个操作符方法中那么
多的限制,因此,你可以像正常的代码一样编写它。它的作用就是,当一段代码
(用户写的,可能是故意,也可以是无意)获取了类或类实例中没有定义的属性时,
程序将做出怎样的反应,而这个回应就在__getattr__方法中,由你来定。

************************************************************


class computer(object):
def __init__(self):
self.brand=""
self.color=""

def set_pro(self,pro):
self.brand,self.color=pro
def get_pro(self):
return self.brand,self.color

c=computer()
print c.get_pro()
print c.set_pro(("gaier","red"))
print c.get_pro()

如果我们的属性很多,这种写法就不合适了,我们可以通过拦截属性解决,即将所
有的获取,赋值操作写在一个拦截属性函数里

class computer2(object):
def __init__(self):
self.brand="1"
self.color=""
def __setattr__(self, key, value):
if key=="pro":
self.brand,self.color=value
else:
self.__dict__[key]=value

def __getattr__(self, item):
if item=="pro":
return self.brand,self.color
else:
raise AttributeError
#print "errors..."

c2=computer2()
# c2.pro=("sanxing","blue")
#
# print c2.pro
# c2.a=4
# print c2.a
# print c2.acd
#print c2.brand


c2.money=12
print c2.money
print c2.abc
print c2.__dict__

*******************************************************
2.7编码问题:



python 有str object 和 unicode object 两种字符串, 都可以存放字符的字节编
码,但是他们是不同的type,这一点很重要,也是为什么会有encode 和decode。

encode 和 decode在pyhton 中的意义可表示为

encode
unicode -------------------------> str(gb2312 or utf-8)
unicode <--------------------------str(gb2312 or utf-8)
decode
几种常用法:
str_string.decode('codec') 是把str_string转换为unicode_string, codec是源str_string的编码方式
unicode_string.encode('codec') 是把unicode_string 转换为str_string,codec是目标str_string的编码方式
str_string.decode('from_codec').encode('to_codec') 可实现不同编码的str_string之间的转换
比如:
>>> t='长城'
>>> t
'xb3xa4xb3xc7'
>>> t.decode('gb2312').encode('utf-8')
'xe9x95xbfxe5x9fx8e'
str_string.encode('codec') 是先调用系统的缺省codec去把str_string转换为
unicode_string,然后用encode的参数codec去转换为最终的str_string. 相当于
str_string.decode('sys_codec').encode('codec')。

*********************************************************
socket(family,type[,protocal]) 使用给定的地址族、套接字类型、协议编号
(默认为0)来创建套接字。

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

服务端socket函数
s.bind(address):将套接字绑定到地址, 在AF_INET下,以元组(host,port)的形式
表示地址.
s.listen(backlog):开始监听TCP传入连接。backlog指定在拒绝连接之前,操作系统
可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。

s.accept():接受TCP连接并返回(conn,address),其中conn是新的套接字对象,可
以用来接收和发送数据。address是连接客户端的地址。

客户端socket函数
s.connect(address):连接到address处的套接字。一般address的格式为元组
(hostname,port),如果连接出错,返回socket.error错误。

s.recv(bufsize[,flag]):接受TCP套接字的数据。数据以字符串形式返回,
bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
s.send(string[,flag]):发送TCP数据。将string中的数据发送到连接的套接字。
返回值是要发送的字节数量,该数量可能小于string的字节大小。
s.sendall(string[,flag]):完整发送TCP数据。将string中的数据发送到连接的套接
字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。

s.close()
关闭套接字。
s.getpeername()
返回连接套接字的远程地址。返回值通常是元组(ipaddr,port)。
s.getsockname()
返回套接字自己的地址。通常是一个元组(ipaddr,port)
*********************************************************
eg1:
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket

ip_port = ('127.0.0.1',9997)

sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)

while True:
print 'server waiting...'
conn,addr = sk.accept()

client_data = conn.recv(1024)
print client_data
conn.sendall('滚蛋!')

conn.close()
----------------
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
ip_port = ('127.0.0.1',9997)

sk = socket.socket()
sk.connect(ip_port)

sk.sendall('我喜欢你')

server_reply = sk.recv(1024)
print server_reply

print sk.getpeername()
print "*****"
print sk.getsockname()

sk.close()

***********************************************
eg2:
#!/usr/bin/env python
#coding:utf-8
import socket

def handle_request(client):
buf = client.recv(1024)
client.send("HTTP/1.1 201 OKkkkkk ")
client.send("Hello, World")

def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost',8082))
sock.listen(5)

while True:
connection, address = sock.accept()
handle_request(connection)
connection.close()

if __name__ == '__main__':
main()

***********************************************
eg3(talking):


#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket


ip_port = ('127.0.0.1',8884)
sk = socket.socket()
sk.connect(ip_port)
print "客户端启动:"
while True:
inp = raw_input('>>>')
sk.sendall(inp)
server_response=sk.recv(1024)
print server_response
if inp == 'exit':
break
sk.close()
-----------------------
#!/usr/bin/env python
# -*- coding:utf-8 -*-


import socket

ip_port = ('127.0.0.1',8884)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)
print "服务端启动..."
while True:
conn,address = sk.accept()
while True:
try:
client_data=conn.recv(1024)
except Exception:
break
print client_data
print "waiting..."
#server_response=raw_input(">>>")
#conn.sendall(server_response)
conn.sendall(client_data)

conn.close()

注意:
当我们断开第一个客户端时,此时server端 client_data=conn.recv(1024)
这里便会接收一个空字符串,从而造成死循环,而windows系统会将这种情况视为
一个错误,UNIX/linux则不会!所以在linux下,只需判断下client_data为空时break
即可解决!

这个问题与3.0/2.0没有关系


*****************************************************
为了解决并发问题,我们采用socketserver模块


#!/usr/bin/env python
# -*- coding:utf-8 -*-
import SocketServer

class MyServer(SocketServer.BaseRequestHandler):

def handle(self):
print "服务端启动..."
while True:
conn = self.request
print self.client_address
while True:
try:
client_data=conn.recv(1024)
except Exception:
break
print client_data
print "waiting..."
#server_response=raw_input(">>>")
#conn.sendall(server_response)
conn.sendall(client_data)

conn.close()
# print self.request,self.client_address,self.server


if __name__ == '__main__':
server = SocketServer.ThreadingTCPServer(('127.0.0.1',8090),MyServer)
server.serve_forever()
----------------------------------------------------



#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket


ip_port = ('127.0.0.1',8090)
sk = socket.socket()
sk.connect(ip_port)
print "客户端启动:"
while True:
inp = raw_input('>>>')
sk.sendall(inp)
server_response=sk.recv(1024)
print server_response
if inp == 'exit':
break
sk.close()

*****************************************************
ssh:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import SocketServer
import subprocess

class MyServer(SocketServer.BaseRequestHandler):

def handle(self):
print "got connection from",self.client_address
while True:

conn=self.request
data=conn.recv(1024)
print "Recv cmd:%s"%data
cmd_call=subprocess.Popen(data,shell=True,stdout=subprocess.PIPE)

cmd_result=cmd_call.stdout.read()
if len(cmd_result)==0:
cmd_result=b"no output!"
conn.send(str(len(cmd_result)))
#conn.recv(1024)
conn.sendall(cmd_result)# 超过1024的部分放到缓存区,并不阻塞在这里

if __name__ == '__main__':
server = SocketServer.ThreadingTCPServer(('127.0.0.1',8091),MyServer)
server.serve_forever()


#dir arp cd ipconfig

-------------------------------
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import socket

ip_port = ('127.0.0.1',8091)
sk = socket.socket()
sk.connect(ip_port)
print "客户端启动:"
while True:
inp = raw_input('>>>')
if len(inp)==0:
continue
if inp=="q":
break
sk.sendall(inp)
res_size=sk.recv(1024)
#sk.send("ok")
print "res_size",res_size
total_size=int(res_size)
received_size=0
while True:

server_response=sk.recv(1024)
received_size+=len(server_response)
if total_size==received_size:

print server_response
break

print server_response


sk.close()

***********************************************************



原文地址:https://www.cnblogs.com/zhming26/p/5545324.html