python之路-基础篇-第七周
一、面向对象进阶-高级语法
1.多态【上节回顾】
python中不存在多态方法,但是我们可以自己实现多态的功能
2.类中的装饰器
1)classmethod
类方法,不能访问实例变量
class Animal(object):
c_name = 100
def __init__(self,name):
self.name = name
@classmethod #类方法
def eat(self): #使用self来调用类变量
print("%s is eating..." % self.c_name) #可以调用类变量
#print("%s is eating..." % self.name) #错误,不能调用实例变量
2)staticmethod
静态方法,不能访问类变量和实例变量
【用途】:没啥用,作为类的“工具箱”,作为一种组织形式
class Animal(object):
c_name = 100
def __init__(self,name):
self.name = name
@staticmethod
def sleep():
print("staticmethod ...")
#print("%s is eating..." % self.c_name) #不能调用类变量
#print("%s is eating..." % self.name) #也不能调用实例变量
3)property
把方法变成属性,
不需要加括号调用
可以访问类变量和实例变量
不能传值,如果要传值,使用.setter的方法
【用途】:私有化
在类变量前面加__:实现变量的私有化,外部实例不能访问该变量
非要访问:_类名称__变量名
3.多继承:广度优先
针对不同的类有点区别:
1)新式类(如class Animal(object)):广度优先
2)经典类(如class Animal):深度优先(python2.x),广度优先(python3.x)
多继承中的优先选择策略:由深度优先向广度优先发展,在python2.x经典类中还使用深度优先的方式,到python3.x中已经全部采用广度优先的方式了,下面是一个广度优先的例子:
class A(object):
n = 100
def f1(self): #BC父类f1方法
print("f1 from A")
class B(A):
n = 100
def f1(self): #D的父类f1方法
print("f1 from B")
class C(A):
n = 100
def f1(self): #D的父类f1方法
print("f1 from C")
class D(B,C):
n = 100
def f1(self): #D的f1方法
print("f1 from D")
d = D()
d.f1()
D的实例需要访问f1方法的时候,优先选择顺序如下:
D --> B --> C --> A
自身方法-->父类1方法-->父类2方法-->父类的父类方法
下面的情形为怎么样?
class A1(object):
n = 100
def f1(self):
print("f1 from A1")
class A2(object):
n = 100
def f1(self):
print("f1 from A2")
class B(A1):
n = 100
# def f1(self):
# print("f1 from B")
class C(A2):
n = 100
def f1(self):
print("f1 from C")
class D(B,C):
n = 100
# def f1(self):
# print("f1 from D")
d = D()
d.f1()
揭晓答案:
#D-->B-->A1-->C-->A2
f1 from A1
4.类的特殊成员
1)new:
class A(object):
def __init__(self):
print("____init___")
def __new__(cls, *args, **kwargs):
print("___new___")
a = A()
#___new___
2)call:
class A(object):
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print("__call__")
a = A()
a()
#__call__
3)__doc__等其他:
class A(object):
""这是一个测试类""
c_name = "alex"
def __init__(self):
self.name = "f"
self.age = 12
self.job = "ITer"
a = A()
print(a.__doc__) #类注释信息
print(a.__module__) #模块名称
print(a.__class__) #模块名称.类名称
print(a.__dict__) #实例变量字典
这是一个测试类
__main__
<class '__main__.A'>
{'age': 12, 'job': 'ITer', 'name': 'f'}
5.反射
bogon:day07 yangfeilong$ more attr_test.py
import sys
class WebServer(object):
def __init__(self,name,host):
self.name = name
self.host = host
def start(self):
print("server is starting...")
def stop(self):
print("server is stoping...")
def restart(self):
self.stop()
self.start()
def run(name):
print("%s is running..." % name)
if __name__ == '__main__':
server = WebServer("server","localhost")
server2 = WebServer("server2","backupserver")
#判断属性和获取属性
if hasattr(server,sys.argv[1]):
func = getattr(server,sys.argv[1])
func()
#修改属性
setattr(server,"s_run",run)
server.s_run("hhha")
#删除属性
delattr(server,"s_run")
#server.s_run("hhha") #删除方法
#删除属性
print(server.name)
delattr(server,"name")
#print(server.name) #删除变量
bogon:day07 yangfeilong$ python3 attr_test.py restart
server is stoping...
server is starting...
hhha is running...
server
二、socket编程
编写一个类shell
服务器端:
import socket
import time
import subprocess
ip_port = ('127.0.0.1',9998)
sk = socket.socket()
sk.bind(ip_port)
sk.listen(5)
while True:
print('server waiting...')
conn,addr = sk.accept()
print(addr)
while True:
client_data = conn.recv(1024)
if not client_data:break
print("recv cmd:",str(client_data,'utf8'))
cmd = str(client_data,"utf8").strip()
cmd_call = subprocess.Popen(cmd,shell=True, stdout=subprocess.PIPE)
cmd_result = cmd_call.stdout.read()
if len(cmd_result) == 0:
cmd_result = b"cmd execution has no output.."
ack_msg = bytes("CMD_RESULT_SIZE|%s" %len(cmd_result) ,"utf8")
conn.send(ack_msg)
client_ack = conn.recv(50)
if client_ack.decode() == 'CLIENT_READY_TO_RECV':
conn.send(cmd_result )
conn.close()
客户端:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
ip_port = ('127.0.0.1',9998)
sk = socket.socket()
sk.connect(ip_port)
while True:
user_input = input("cmd:").strip()
if len(user_input) == 0:continue
if user_input == 'q':break
sk.send(bytes(user_input,'utf8'))
#ack_msg = b"CMD_RESULT_SIZE|%s" % len(cmd_result)
server_ack_msg = sk.recv(100)
cmd_res_msg = str(server_ack_msg.decode()).split("|")
print("server response:",cmd_res_msg)
if cmd_res_msg[0] =="CMD_RESULT_SIZE":
cmd_res_size = int(cmd_res_msg[1])
sk.send(b"CLIENT_READY_TO_RECV")
res = ''
received_size = 0
while received_size < cmd_res_size:
data = sk.recv(500)
received_size += len(data)
res += str(data.decode())
else:
print(str(res))
print('-------recv done----')
sk.close()