1 接口与归一化设计

1.1 归一化概念:

  归一化的好处:

  1.归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了,这极大降低了使用者的使用难度。

  2.归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合

  继承的两种用途

  一:继承基类的方法,并且做出自己改变或者扩展(代码重用):实践中,继承的这种用途意义并不很大,甚至常常是有害的。因为它使得子类与基类出现强耦合。

  二:声明某个子类兼容于某基类,定义一个接口类(模仿java的Interface),接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能

class Interface:
'''
定义接口Interface类来模仿接口的概念,
python中压根就没有interface关键字来定义一个接口。
'''
def read(self): # 定接口函数read
pass def write(self): # 定义接口函数write
pass class Txt(Interface): # 文本,具体实现read和write
def read(self):
print('文本数据的读取方法') def write(self):
print('文本数据的读取方法') class Sata(Interface): #磁盘,具体实现read和write
def read(self):
print('硬盘数据的读取方法') def write(self):
print('硬盘数据的读取方法') class Process(Interface):
def read(self):
print('进程数据的读取方法') def write(self):
print('进程数据的读取方法') t = Txt()
s = Sata()
p = Process() t.read() # 运行结果:文本数据的读取方法
s.read() # 运行结果:硬盘数据的读取方法
p.read() # 运行结果:进程数据的读取方法

1.2 抽象类

  了解知识点

  与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化

  借助abc模块,进行模拟抽象类

import abc
class Interface(metaclass=abc.ABCMeta):
'''
定义接口Interface类来模仿接口的概念,
python中压根就没有interface关键字来定义一个接口。
'''
@abc.abstractmethod
def read(self): # 定接口函数read
pass
@abc.abstractmethod
def write(self): # 定义接口函数write
pass class Txt(Interface): # 文本,具体实现read和write
def read(self):
pass def write(self):
pass t = Txt()

1.3 多态

  面向对象的多态、多态性

  多态:指的是同一种事物的多种形态

  动物有多种形态:人、狗、猪

# 多态:同一种事物的多种形态
class Animal: # 同一类事物:动物
def talk(self):
pass class People(Animal): # 动物的形态之一:人
def talk(self):
print('say hello') class Dog(Animal): # 动物的形态之二:狗
def talk(self):
print('say wangwang') p=People()
d=Dog()
p.talk()
d.talk()

1.4 多态性

  多态性:可以在不考虑实例类型的前提下使用实例

# 多态:同一种事物的多种形态
class Animal: # 同一类事物:动物
def talk(self):
pass class People(Animal): # 动物的形态之一:人
def talk(self):
print('say hello') class Dog(Animal): # 动物的形态之二:狗
def talk(self):
print('say wangwang') # 多态性:可以在不考虑实例类型的前提下使用实例
p=People()
d=Dog() def Talk(animal):
animal.talk() Talk(p)
Talk(d)

1.5 多态性的好处

  多态性的好处:

  1.增加了程序的灵活性

  2.增加了程序可扩展性

1.6 鸭子类型

  Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’

  python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象

  也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。

  利用标准库中定义的各种‘与文件类似’的对象,尽管这些对象的工作方式像文件,但他们没有继承内置文件对象的方法

# 二者都像鸭子,二者看起来都像文件,因而就可以当文件一样去用
class TxtFile:
def read(self):
pass def write(self):
pass class DiskFile:
def read(self):
pass
def write(self):
pass

2 封装

2.1 隐藏

  在python中用双下划线开头的方式将属性隐藏起来

class Foo:
__N = 1111 # _Foo__N
def __init__(self,name):
self.__Name=name # self._Foo__Name=name def __f1(self): # _Foo__f1
print('f1')
def f2(self):
self.__f1() # self._Foo__f1() f = Foo('egon')
# print(f.__N) # 把数据类型隐藏起来了 # 这种隐藏需要注意的问题:
# 1:这种隐藏只是一种语法上变形操作,并不会将属性真正隐藏起来
print(Foo.__dict__)
print(f.__dict__) # 运行结果:{'_Foo__Name': 'egon'}
print(f._Foo__Name) # 运行结果:egon
print(f._Foo__N) # 运行结果:1111 # 2:这种语法级别的变形,是在类定义阶段发生的,并且只在类定义阶段发生
Foo.__x = 123123
print(Foo.__dict__) # 运行结果:...'__doc__': None, '__x': 123123}
print(Foo.__x) # 运行结果:123123
f.__x = 123123123
print(f.__dict__) # 运行结果:{'_Foo__Name': 'egon', '__x': 123123123}
print(f.__x) # 运行结果:123123123 # 3:在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,
# 而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时, # 子类是无法覆盖的。
class Foo:
def __f1(self): # _Foo__f1
print('Foo.f1') def f2(self):
self.__f1() # self._Foo_f1 class Bar(Foo):
def __f1(self): # _Bar__f1
print('Bar.f1') b = Bar()
b.f2() # 运行结果:Foo.f1

2.2 封装数据属性

# 封装不是单纯意义的隐藏
# 1:封装数据属性:将属性隐藏起来,然后对外提供访问属性的接口,
# 关键是我们在接口内定制一些控制逻辑从而严格控制使用对数据属性的使用
class People:
def __init__(self,name,age):
if not isinstance(name,str):
raise TypeError('%s must be str' %name)
if not isinstance(age,int):
raise TypeError('%s must be int' %age)
self.__Name=name
self.__Age=age
def tell_info(self):
print('<名字:%s 年龄:%s>' %(self.__Name,self.__Age)) def set_info(self,x,y):
if not isinstance(x,str):
raise TypeError('%s must be str' %x)
if not isinstance(y,int):
raise TypeError('%s must be int' %y)
self.__Name=x
self.__Age=y p=People('egon',18)
p.tell_info() # 运行结果:<名字:egon 年龄:18> p.set_info('Egon',19)
p.tell_info() # 运行结果:<名字:egon 年龄:19>

2.3 封装函数属性

  封装函数属性的目的:隔离复杂度

# 2:封装函数属性:为了隔离复杂度
# 取款是功能,而这个功能有很多功能组成:插卡、密码认证、输入金额、打印账单、取钱
# 对使用者来说,只需要知道取款这个功能即可,其余功能我们都可以隐藏起来,很明显这么做
# 隔离了复杂度,同时也提升了安全性 class ATM:
def __card(self):
print('插卡')
def __auth(self):
print('用户认证')
def __input(self):
print('输入取款金额')
def __print_bill(self):
print('打印账单')
def __take_money(self):
print('取款') def withdraw(self):
self.__card()
self.__auth()
self.__input()
self.__print_bill()
self.__take_money() a = ATM()
a.withdraw()
# 运行结果:
# 插卡
# 用户认证
# 输入取款金额
# 打印账单
# 取款

2.4 静态属性

class Foo:
@property
def f1(self):
print('Foo.f1') f = Foo()
f.f1 # 运行结果:Foo.f1

  示例:计算BMI指数

'''
例:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,
如果我们将其做成一个属性,更便于理解)
成人的BMI数值:
过轻:低于18.5
正常:18.5-23.9
过重:24-27
肥胖:28-32
非常肥胖, 高于32
  体质指数(BMI)=体重(kg)÷身高^2(m)
  EX:70kg÷(1.75×1.75)=22.86
'''
class People:
def __init__(self,name,weight,height):
self.name=name
self.weight=weight
self.height=height
@property
def bmi(self):
return self.weight / (self.height**2) p=People('jack',75,1.80)
p.height=1.86
print(p.bmi)

3 面向对象高级

3.1 反射

  通过字符串,反射到真实的属性上,找到真实的属性

class Foo:
x=1
def __init__(self,name):
self.name = name def f1(self):
print('from f1') print(Foo.x) # Foo.__dict__['x'] f = Foo('egon')
print(f.__dict__) print(f.name)
print(f.__dict__['name']) # hasattr
print(hasattr(f,'name')) # f.name
print(hasattr(f,'f1')) # f.f1
print(hasattr(f,'x')) # f.x # setattr
setattr(f,'age',18) # f.age=18 # getattr
print(getattr(f,'name')) # f.name
print(getattr(f,'abc',None)) # f.abc
print(getattr(f,'name',None)) # f.abc func = getattr(f,'f1') # f.f1
func() # delattr
delattr(f,'name') # del f.name
print(f.__dict__)

3.2 item系列

  Item系类,主要包括:__getitem__、__setitem__、 __delitem__,通过这几个item,可以像操作字典一样,操作对象的属性。

class Foo:
def __getitem__(self, item):
print('=====>get')
return self.__dict__[item] def __setitem__(self, key, value):
self.__dict__[key]=value
# setattr(self,key,value) def __delitem__(self, key):
self.__dict__.pop(key) f = Foo()
f['name'] = "jack" # 设置
print(f["name"]) # 取出属性
del f["name"] # 删除
print(f.__dict__)

3.3 __str__

  通过__str__,打印对象信息

class People:
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex def __str__(self): # 在对象被打印时触发执行
return '<name:%s age:%s sex:%s>' %(self.name,self.age,self.sex) p=People('alex',38,'male')
print(p) # 运行结果:<name:alex age:38 sex:male>

3.4 析构方法

  用法:清理一些资源,清理一些python解析器不能清理的资源,例如:清理操作系统的资源,打开文件,向操作系统发起调用,关闭文件句柄资源

class Foo:
def __init__(self, name):
self.name = name def __del__(self): # 在对象资源被释放时触发
print('-----del------') f = Foo("mary")
del f
print('对象被释放')

4 异常

# 逻辑错误
# TypeError
for i in 3:
pass # NameError
aaaaa # ValueError
int('asdfsadf') # IndexError
l=[1,2]
l[1000] #KeyError
d = {'a':1}
d['b'] # AttributeError
class Foo:pass
Foo.x

4.1 异常处理

  如果错误发生的条件可预知的,我们需要用if进行处理,在错误发生之前进行预防

  如果错误发生的条件时不可预知的,则需要用到try…except,在错误发生之后进行处理

#基本语法为
try:
# 被检测的代码块
except 异常类型:
# try中一旦检测到异常,就执行这个位置的逻辑
# 示例
try:
f=open('a.txt')
g=(line.strip() for line in f)
print(next(g))
print(next(g))
except StopIteration:
f.close()

4.2 多分支异常

try:
aaaa
print('====>1')
l = []
l[3]
print('====>2')
d = {}
d['x']
print('====>3')
except NameError as e:
print(e)
except IndexError as e:
print(e)
except KeyError as e:
print(e)

4.3 万能异常

try:
# aaaa
print('====>1')
l = []
l[3]
print('====>2')
except Exception as e:
print(e)

4.4 基本结构

try:
aaaa
print('====>1')
l=[]
l[3]
print('====>2')
d={}
d['x']
print('====>3')
except NameError as e:
print(e)
except IndexError as e:
print(e)
except KeyError as e:
print(e)
except Exception as e:
print(e)
else:
print('在没有错误的时候执行')
finally:
print('无论有无错误,都会执行')

4.5 自定义异常

class EgonException(BaseException):
def __init__(self, msg):
self.msg=msg
def __str__(self):
return '<%s>' %self.msg raise EgonException('jack 的异常')

5 Socket编程

  IP + 端口,标识唯一一个软件、应用

  tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端

5.1 简单套接字

5.1.1 服务端

import socket

# 买手机
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 插卡
phone.bind(("127.0.0.1", 8080)) # 开机
phone.listen(5) # 等待电话
print("server start...")
conn,client_addr = phone.accept() # tcp链接,client_addr
print("链接", conn)
print(client_addr) # 基于建立的链接,收发消息
client_data = conn.recv(1024)
print("客户端的消息", client_data)
conn.send(client_data.upper()) # 挂电话链接
conn.close() # 关机
phone.close()

5.1.2 客户端

import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080)) phone.send("hello".encode("utf-8"))
server_data = phone.recv(1024)
print("服务端回应的消息", server_data)
phone.close() 

5.2 加上通信循环

5.2.1 服务端

import socket

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...")
conn,client_addr = phone.accept() while True: # 通讯循环
client_data = conn.recv(1024)
print("客户端的消息", client_data)
conn.send(client_data.upper()) conn.close()
phone.close()

5.2.2 客户端

import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080)) while True:
msg = input(">>").strip()
if not msg:continue
phone.send(msg.encode("utf-8"))
server_data = phone.recv(1024)
print("server back:", server_data.decode("utf-8")) phone.close()

5.3 加上链接循环

5.3.1 服务端

import socket

phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...") while True: # 链接循环
conn,client_addr = phone.accept()
while True: # 通讯循环
try:
client_data = conn.recv(1024)
if not client_data:break # 针对linux系统
conn.send(client_data.upper())
except Exception: # 针对windows
break
conn.close() phone.close()

5.3.2 客户端

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080)) while True:
msg=input('>>: ').strip()
if not msg:continue
phone.send(msg.encode('utf-8'))
server_data = phone.recv(1024)
print(server_data.decode('utf-8')) phone.close()

5.4 模拟ssh远程执行命令

5.4.1 服务端

import socket
import subprocess phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...") while True: # 链接循环
conn,client_addr = phone.accept()
while True: # 通讯循环
try:
cmd = conn.recv(1024)
if not cmd:break # 针对linux系统 # 执行命令,拿到结果
res = subprocess.Popen(cmd.decode("utf-8"),
shell = True,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
stdout = res.stdout.read()
stderr = res.stderr.read()
conn.send(stdout+stderr)
except Exception: # 针对windows
break
conn.close() phone.close()

5.4.2 客户端

import socket
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',8080)) while True:
cmd = input('>>').strip()
if not cmd:continue
# 发命令
phone.send(cmd.encode('utf-8')) # 收命令的执行结果
cmd_res = phone.recv(1024) # 打印结果
print(cmd_res.decode('gbk')) phone.close()

5.5 粘包现象

  Tcp出现粘包现象,udp不会出现粘包;主要是tcp基于流式的,像水流一样,没有开头,没有结尾,源源不断,会发生粘包;udp,是数据报的,不会出现粘包。

5.5.1 服务端

from socket import *
s = socket(AF_INET, SOCK_STREAM)
s.bind(("127.0.0.1", 8080))
s.listen(5) conn,addr = s.accept() # 收发消息
data1 = conn.recv(1024)
print("data1:", data1) data2 = conn.recv(1024)
print("data2:", data2) conn.close()
s.close()

5.5.2 客户端

from socket import *
c = socket(AF_INET, SOCK_STREAM)
c.connect(("127.0.0.1", 8080)) c.send("hello".encode("utf-8"))
c.send("world".encode("utf-8"))
c.close()

5.6 ssh远程执行命令+定制报头

5.6.1 服务端

import socket
import struct
import subprocess
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...")
while True: # 链接循环
conn,client_addr = phone.accept()
print(conn, client_addr) while True: # 通讯循环
try:
cmd = conn.recv(1024)
if not cmd:break # 执行命令,拿到结果
res = subprocess.Popen(cmd.decode("utf-8"),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = res.stdout.read()
stderr = res.stderr.read() # 制作报头
header = struct.pack("i", len(stdout)+len(stderr)) # 先发报头(固定长度)
conn.send(header)
# 再发真实数据
conn.send(stdout)
conn.send(stderr)
except Exception: # 针对windows
break
conn.close() phone.close()

5.6.2 客户端

import socket
import struct phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080)) while True:
cmd = input(">>").strip()
if not cmd:continue
# 发命令
phone.send(cmd.encode("utf-8")) # 先收报头
header = phone.recv(4)
total_size = struct.unpack("i", header)[0] # 再收命令的执行结果
recv_size = 0
data = b""
while recv_size < total_size:
recv_data = phone.recv(1024)
recv_size += len(recv_data)
data += recv_data # 打印结果
print(data.decode("gbk")) phone.close()

5.7 定制报头的正确方式

5.7.1 服务端

import socket
import struct
import subprocess
import json
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
print("server start...")
while True: # 链接循环
conn,client_addr = phone.accept()
print(conn, client_addr) while True: # 通讯循环
try:
cmd = conn.recv(1024)
if not cmd:break # 执行命令,拿到结果
res = subprocess.Popen(cmd.decode("utf-8"),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout = res.stdout.read()
stderr = res.stderr.read() # 制作报头
header_dic = {"total_size":len(stdout)+len(stderr), "md5":None}
header_json = json.dumps(header_dic)
header_bytes = header_json.encode("utf-8") # 1.先发报头的长度(固定4个bytes)
conn.send(struct.pack("i", len(header_bytes))) # 2.再发报头
conn.send(header_bytes) # 3.最后发真实数据
conn.send(stdout)
conn.send(stderr)
except Exception: # 针对windows
break
conn.close() phone.close()

5.7.2 客户端

import socket
import struct
import json phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080)) while True:
cmd = input(">>").strip()
if not cmd:continue
# 发命令
phone.send(cmd.encode("utf-8")) # 先收报头的长度
struct_res = phone.recv(4)
header_size = struct.unpack("i", struct_res)[0] # 再收报头
header_bytes = phone.recv(header_size)
print(header_bytes)
head_json = header_bytes.decode("utf-8")
head_dic = json.loads(head_json) total_size = head_dic["total_size"] # 再收命令的执行结果
recv_size = 0
data = b""
while recv_size < total_size:
recv_data = phone.recv(1024)
recv_size += len(recv_data)
data += recv_data # 打印结果
print(data.decode("gbk")) phone.close()

5.8 服务端实现并发

5.8.1 服务端

import socketserver

class MyTcphandler(socketserver.BaseRequestHandler):
def handle(self):
while True: # 通信循环
print(self.request)
data = self.request.recv(1024)
self.request.send(data.upper()) if __name__ == '__main__':
# 取代链接循环
server = socketserver.ThreadingTCPServer(("127.0.0.1",8080), MyTcphandler)
server.serve_forever()

5.8.2 客户端

import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080)) while True:
msg = input(">>").strip()
if not msg:continue
phone.send(msg.encode("utf-8"))
server_data = phone.recv(1024)
print(server_data.decode("utf-8"))
phone.close()

面向对象&网络编程的更多相关文章

  1. Java面向对象 网络编程 下

    Java面向对象 网络编程  下 知识概要:                   (1)Tcp 练习 (2)客户端向服务端上传一个图片. (3) 请求登陆 (4)url 需求:上传图片. 客户端:   ...

  2. Java面向对象 网络编程 上

     Java面向对象 网络编程 上 知识概要:                     (1)网络模型 (2)网络通讯要素 (3)UDP TCP 概念 (4)Socket (5)UDP TCP 传输 ...

  3. 第三模块:面向对象&网络编程基础 第2章 网络编程

    01-计算机基础 02-什么是网络 03-五层协议详解 04-传输层详解 05-什么是Socket 06-基于socket实现简单套接字通信 07-在简单套接字基础上加上通信循环 08-客户端与服务端 ...

  4. 第三模块:面向对象&网络编程基础 第1章 面向对象

    我的失败与梦想(一) 我的失败与梦想之为何创办路飞学城 01-编程范式 02-面向过程编程 03-面向对象编程介绍 04-定义类与实例化出对象 05-如何使用类 06-如何使用对象 07-属性查找与绑 ...

  5. 第三模块 面向对象& 网络编程基础 实战考核

    1.简述构造方法和析构方法. 构造方法(__init__):主要作用是实例化时给实例一些初始化参数,或执行一些其它的初始化工作,总之因为这个__init__只要一实例化, 就会自动执行,不管你在这个方 ...

  6. 第三模块:面向对象&网络编程基础 第3章 选课系统作业讲解

    01-选课系统作业讲解1 02--选课系统作业讲解2 03-选课系统作业讲解3 04--选课系统作业讲解4 01-选课系统作业讲解1 02--选课系统作业讲解2 03-选课系统作业讲解3 04--选课 ...

  7. 第三模块:面向对象&网络编程基础 第4章 FTP项目作业讲解

    01-FTP项目需求 02-FTP项目框架搭建 03-FTP项目用户认证 04--FTP项目制定标准定长消息头 05-FTP项目下载功能开发 06-FTP项目下载功能开发2 07-FTP项目ls文件列 ...

  8. 有哪些适合学生参与的 C++,网络编程方面的开源项目?

    有哪些适合学生参与的 C++,网络编程方面的开源项目?   Tinyhttpd是一个超轻量型Http Server,使用C语言开发,全部代码只有502行(包括注释),附带一个简单的Client,可以通 ...

  9. C++网络编程方面的开源项目

    Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力. ...

随机推荐

  1. Linux Samba服务主配文件smb.conf中文详解【转】

    转自:https://blog.csdn.net/maotianwang/article/details/52524732 从网上找到描述比较详细的smb.conf中文解释: 服务名:smb 配置目录 ...

  2. Win7 启动修复

    先让我们看一下windows7的启动过程的常识:电脑加电后,首先是启动BIOS程序,BIOS自检完毕后,找到硬盘上的主引导记录MBR,MBR读取DPT(分区表),从中找出活动的主分区,然后读取活动主分 ...

  3. 转载:《理解OAuth 2.0》 阮一峰

    原文:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛 ...

  4. WebMvcConfigurerAdapter已过时

    Spring Boot2.0的版本(创建的时候自动选择的这个版本),然后编译器告诉我WebMvcConfigurerAdapter已过时了 @Deprecated public abstract cl ...

  5. activiti 基础

    一:activiti 入门 作者:fenng 商丘 工作流(Workflow) 就是业务过程的部分或整体在计算机应用环境下的自动化主要解决的是"使在多个参与者之间按照某种定义的规则传递文档, ...

  6. tomcat 输入学习

    Tomcat学习—Tomcat7 修改/webapps/ROOT发布路径(Linux和windows环境) https://blog.csdn.net/u010648555/article/detai ...

  7. python接口自动化测试五:乱码、警告、错误处理

    乱码: 以content字节流输出,解码成utf-8: print(r.encoding)   # 查看返回的编码格式: 去掉Warning警告: import urllib3 urllib3.dis ...

  8. Unicode转义序列

    声明: web前端学习笔记,欢迎大神指点.联系QQ:1522025433. Javascipt 定义了一种特殊序列,使用6位ASCII字符代表任意16Unicode内码.这些Unicode转义序列均以 ...

  9. 使用vmware提示无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件

    问题描述 打开虚拟机时候提示 “vmware没有正常关闭,再次打开使用时蓝屏,在安全模式下再次打开不会蓝屏,但提示“无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件,你想要安 ...

  10. webpack 使用环境变量

    要在开发和生产构建之间,消除 webpack.config.js 的差异.你可能需要环境变量. 可以使用 Node.js 模块的标准方式:在运行 webpack 时设置环境变量,并且使用 Node.j ...