python 全栈开发,Day11(函数名应用,闭包,装饰器初识,带参数以及带返回值的装饰器)
一、函数名应用
函数名是什么?函数名是函数的名字,本质:变量,特殊的变量。
函数名(),执行此函数。
python 规范写法
1. #后面加一个空格,再写内容,就没有波浪线了。
2.一行代码写完,下面一行的的内容要空2行,
3.逗号2个边的内容要有空格。
如果是不规范的写法,Pycharm编辑器,会有灰色的波浪线显示。
1.单独打印函数名
def func1():
print(666) print(func1)
执行输出:
<function func1 at 0x000001455800A950>
打印的是一个函数内存地址
2.函数名的赋值
def func2():
print(666) f = func2
print(f())
执行输出:
666
None
3.函数名可以作为容器类数据的元素
下面的函数都要执行
def f1():
print(111) def f2():
print(222) def f3():
print(333) def f4():
print(444)
写4个执行代码就可以了
f1()
f2()
f3()
f4()
如果是100个呢?
使用for循环批量执行函数
def f1():
print(111) def f2():
print(222) def f3():
print(333) def f4():
print(444) l1 = []
for i in range(1, 5):
l1.append('f' + str(i)) for i in l1:
eval(i)()
执行输出:
111
222
333
444
4.函数名可以作为参数
def f1():
print(666) def f2(x):
x() f2(f1)
执行输出:
666
分析如下:
def f1():
print() def f2(x): # x = f1
x() # f1() f2(f1) #将f1函数作为变量传参给f2,x()表示执行函数f1(),输出666
5.函数名可以作为函数的返回值。
def f11(x):
return x #将返回值传给调用者f11(5),此时ret = 5 ret = f11(5)
print(ret)
执行输出:
5
def f1():
print(666) def f2(x):
return x f2(f1)()
执行输出:
666
代码分析:
def f1():
print(666) def f2(x): # x = f1
return x #将f1返回给函数调用者f2(f1),此时就相当于 f1 = f2(f1) f2(f1)() #将f1函数作为变量传参给f2,return之后f2(f1)等于f1,f1()就表示执行f1函数,输出666
f1是一个特殊变量,加()就可以执行了
第一类对象( first-class object)指
1.可在运行期创建
2.可用作函数参数或返回值
3.可存入变量的实体
*不明白?那就记住一句话,就当普通变量用
函数名就是第一类对象
加括号,就可以执行了。
二、闭包
闭包函数:
内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数
有如下代码,请补全代码,在函数外部执行inner()函数
def wrapper():
def inner():
print(666)
第一种写法
def wrapper():
def inner():
print(666)
inner() wrapper()
执行输出:
666
第二种写法
def wrapper():
def inner():
print(666)
return inner #将inner函数返回给调用者ret,此时ret = inner ret = wrapper()
ret() #执行inner函数
执行输出:
666
ret = wrapper()
ret()
等同于
wrapper()()
return inner之后,inner由临时空间,转换为全局空间了。
因为ret赋值了
闭包举例
def wrapper():
name = '老男孩'
def inner():
print(name)
inner() wrapper()
执行输出:
老男孩
如何判断它是否是一个闭包函数呢? 内层函数名.__closure__ cell 就是=闭包
def wrapper():
name = '老男孩'
def inner():
print(name)
inner()
print(inner.__closure__) wrapper()
执行输出:
老男孩
(<cell at 0x0000017FC9C90B58: str object at 0x0000017FCA349AD0>,)
出现了cell,就表示它是一个闭包函数
name = '老男还'
def wrapper():
def inner():
print(name)
inner()
print(inner.__closure__) wrapper()
执行输出:
老男还
None
返回值为None 表示它不是闭包
因为name是一个全局变量
如果函数调用了外层变量而非全局变量,那么它就是闭包
name = '老男还'
def wrapper2():
name1 = 'alex'
def inner():
print(name)
print(name1)
inner()
print(inner.__closure__) wrapper2()
执行输出:
老男还
alex
(<cell at 0x000001F87DBC0B58: str object at 0x000001F87E096E68>,)
只要引用了外层变量至少一次,非全局的,它就是闭包
面试题:
下面的函数,是一个闭包吗?
name = '老男孩'
def wraaper2(n):
# n = '老男孩' 相当于
def inner():
print(n)
inner()
print(inner.__closure__) # None
wraaper2(name)
它也是一个闭包
虽然wraaper2传了一个全局变量,但是在函数wraaper2内部,inner引用了外层变量,相当于在函数inner外层定义了n = '老男孩',所以inner是一个闭包函数
闭包的好处
当函数开始执行时,如果遇到了闭包,他有一个机制,他会永远开辟一个内存空间,将必包中的变量等值放入其中,不会随着函数的执行完毕而消失。
举一个例子
from urllib.request import urlopen
content = urlopen('http://www.xiaohua100.cn/index.html').read().decode('utf-8')
print(content)
执行输出,是一堆网页源代码。
爬3次
from urllib.request import urlopen
content1 = urlopen('http://www.xiaohua100.cn/index.html').read().decode('utf-8')
content2 = urlopen('http://www.xiaohua100.cn/index.html').read().decode('utf-8')
content3 = urlopen('http://www.xiaohua100.cn/index.html').read().decode('utf-8')
内存开了3次,很占用内存
把它封装成闭包
from urllib.request import urlopen def index():
url = "http://www.xiaohua100.cn/index.html"
def get():
return urlopen(url).read()
return get xiaohua = index()
content = xiaohua()
print(content)
这个例子,只有第一遍,是从网站抓取的。
之后的执行,直接从内存中加载,节省内存空间
三、装饰器初识
装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。
装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景。
现在我有一个需求,我想让你测试这个函数的执行时间,在不改变这个函数代码的情况下:
先写一个雏形
import time def func1():
print('in func1')
time.sleep(1) # 模拟程序逻辑 start = time.time()
func1()
print(time.time() - start)
执行输出:
in func1
1.0001070499420166
封装成函数
传一个参数,函数名,就可以查看函数的执行时间了
import time def func1():
print('in func1')
time.sleep(1) # 模拟程序逻辑 def timmer(f):
start_time = time.time()
f()
end_time = time.time()
print('此函数的执行时间为{}'.format(end_time - start_time)) timmer(func1)
执行输出:
in func1
此函数的执行时间为1.0002098083496094
原来100个函数,都是调用了func1(),现在测试函数,需要timeer(func1)。如果想测试所有调用地方的执行时间,那么需要修改100个函数位置,改成timeer(func1),太麻烦了。
不能更改原来的调用方式,同时需要加一个函数执行时间的功能。怎么办呢?
要无限接近于原来的调用方法,慢慢来
先来讲一个变量赋值的例子
a = 1
b = a
a = 2 #a重新赋值了,原来a的值不存在了。但是b还是等于原来a的值,也就是1
print(a,b)
执行输出2,1
1.更改执行方式
import time def func1():
print('in func1')
time.sleep(1) # 模拟程序逻辑 def timmer(f):
start_time = time.time()
f()
end_time = time.time()
print('此函数的执行时间为{}'.format(end_time - start_time)) f1 = func1 #定义f1等于func1函数
func1 = timmer #定义func1等于timmer,等式计算右边的。此时func1被覆盖了,和原来的没有任何关系,f1还是等于原来的func1
func1(f1) #此时相当于执行 timmer(老的func1)
执行输出:
in func1
此函数的执行时间为1.0001263618469238
在精简一步
import time def func1():
print('in func1')
time.sleep(1) # 模拟程序逻辑 def timmer(f): # f = func1
def inner():
start_time = time.time()
f() #执行func1()
end_time = time.time()
print('此函数的执行时间为{}'.format(end_time - start_time))
return inner #将inner函数返回给函数调用者timmer(func1) a = timmer(func1) #等式计算右边的,将func1函数传给timmer函数
a() #此时相当于执行了inner函数
执行输出:
in func1
此函数的执行时间为1.000577449798584
最终版本
import time def timmer(f): # 2接收参数.f = func1
def inner():
start_time = time.time() #5.进入inner函数
f() #6.执行f(),也就是原来的func1函数。虽然func1被覆盖了,但是之前的值还存在。请参考上面a,b赋值的例子
end_time = time.time() #10 获取当前时间
print('此函数的执行时间为{}'.format(end_time - start_time)) #11.输出差值
return inner #3.将inner函数返回给函数调用者timmer(func1),此时程序结束,继续执行func1() def func1(): #7.进入函数
print('in func1') # 8.打印输出
time.sleep(1) # 9.等待1秒 func1 = timmer(func1) #1.等式计算右边的,将func1函数传给timmer函数,此时func1被覆盖了,原来func1的不存在了。
func1() #4.这里的func1是全新的func1,就是上面的赋值,此时相当于执行 inner函数
代码从上至下执行,先加载函数变量timmer和func1。在执行上文说的第1步以及后面的,请看数字。
执行输出:
in func1
此函数的执行时间为1.0009608268737793
但是加这一步,还是不太方便。那么python给这种情况,加了一个语法糖@
语法糖指那些没有给计算机语言添加新功能,而只是对人类来说更"甜蜜"的语法
import time def timmer(f): # f = func1
def inner():
start_time = time.time()
f() #执行func1()
end_time = time.time()
print('此函数的执行时间为{}'.format(end_time - start_time))
return inner #将inner函数返回给函数调用者timmer(func1) #语法糖@
@timmer #相当于 func1 = timmer(func1) #这一步就已经覆盖了
def func1():
print('in func1')
time.sleep(1) # 模拟程序逻辑 func1() #相当于执行了inner()函数
想测试谁,前面加@装饰器函数,即可。
装饰器利用return制造了一个假象,func1()执行,其实是执行了inner()
func1()已经把原来的func1()给覆盖了
这个装饰器,还不够完整,函数不能传参数
先来举个例子
def func2(a1,b1): #4.执行函数,接收位置参数a1=1,b1=2
print(a1,b1) #5. 输出1,2
def func3(a,b): #2. 接收参数,a=1,b=2
func2(a,b) #3. 执行函数func2(1,2)
func3(1,2) #1.传位置参数1,2
执行输出:
1 2
func3执行一遍后,将a,b的值,传给a1,b1了
上面装饰器的例子,func1,要传2个参数a,b
import time def timmer(f):
def inner(a,b):
start_time = time.time()
f(a,b)
end_time = time.time()
print('此函数的执行时间为{}'.format(end_time - start_time))
return inner @timmer
def func1(a,b):
print('in func1 {}{}'.format(a,b))
time.sleep(1) # 模拟程序逻辑 func1(1,2)
执行输出:
in func1 12
此函数的执行时间为1.0006024837493896
如果有多个参数呢?改成动态参数
import time def timmer(f):
def inner(*args,**kwargs):
start_time = time.time()
f(*args,**kwargs)
end_time = time.time()
print('此函数的执行时间为{}'.format(end_time - start_time))
return inner @timmer
def func1(*args,**kwargs):
print('in func1 {}{}'.format(args,kwargs))
time.sleep(1) # 模拟程序逻辑 func1(1,2,a='3',b=4)
执行输出:
in func1 (1, 2){'b': 4, 'a': '3'}
此函数的执行时间为1.000101089477539
面试题,手写一个装饰器
写装饰器,约定俗成,函数名为wrapper
第一步
def wrapper(func):
def inner():
func()
return inner
第二步
def wrapper(func):
def inner(*args,**kwargs):
func(*args,**kwargs)
return inner
第三步
def wrapper(func):
def inner(*args,**kwargs):
'''被装饰函数之前'''
ret = func(*args,**kwargs)
'''被装饰函数之后'''
return ret
return inner
完整的
def wrapper(func):
def inner(*args,**kwargs):
'''被装饰函数之前'''
ret = func(*args,**kwargs)
'''被装饰函数之后'''
return ret
return inner @wrapper
def func(*args,**kwargs):
print(args,kwargs)
return 666 print(func())
作业:
使用函数完成用户登录和注册功能
#先让用户选择,是登陆还是注册
#选择序号完毕之后,运行相应的程序,
#验证成功之后,可以让其继续选择,登陆还是注册,还可以选择退出。
1.先准备函数的雏形
def registered_username(username):
'''
#判断注册用户名是否存在
:param username: 用户名
:return: True 存在 False 不存在
''' def write_file(username,password):
'''
#写入用户列表文件
:param username: 用户名
:param password: 密码
:return: True 写入成功 False 写入失败
''' def username_password(username,password):
'''
#判断用户名和密码是否匹配
:param username: 用户名
:param password: 密码
:return: True 匹配成功 False 匹配失败
''' def register(*args,**kwargs):
'''
注册逻辑
:return:
'''
pass def login(*args,**kwargs):
'''
登录逻辑
:return:
'''
pass def user_menu(*args,**kwargs):
'''
# 用户菜单
'''
pass
2.先写菜单
def user_menu(*args,**kwargs):
'''
# 用户菜单
'''
# 判断文件是否存在,不存在创建文件
file_exists()
# 循环
while True:
# 打印菜单
menu = ['注册', '登录', '退出']
print('bbs系统'.center(25, '#'))
for i in range(len(menu)):
print('{}\t{}'.format(i + 1, menu[i]))
print(''.center(27, '#'))
number = input('请选择序号: ').strip()
if number == '1':
# 执行注册程序
register()
elif number == '2':
# 执行登录程序
login()
elif number == '3':
exit()
else:
print('输入错误,请重新输入!')
3.写判断用户列表文件是否存在
def file_exists(*args,**kwargs):
'''
# 判断用户列表文件是否存在
:return: True 存在 False 不存在
'''
# 判断文件是否存在
if os.path.exists(file_name):
return True
else:
with open(file_name, encoding='utf-8', mode='w') as mk:
mk.write('张三 123')
return False
4.再写注册逻辑
def register(*args,**kwargs):
'''
注册逻辑
:return:
'''
while True:
username = input('请输入注册的用户名,或输入q返回菜单:').strip()
if username == '':
print('用户名为空,请重新输入!')
elif username.upper() == 'Q':
break
else:
# 执行判断用户名函数
result = registered_username(username)
if result:
password = input('请输入您的注册的密码:').strip()
# 判断密码
if password == '':
print('密码为空,请重新输入!')
else:
# 执行写入用户列表文件函数
result = write_file(username, password)
if result:
print('注册成功!,您的用户名为: {}\n倒计时2秒返回菜单!'.format(username))
time.sleep(2)
user_menu()
else:
print('注册失败!请重试')
else:
print('用户名已经存在,请重新输入!')
5.判断注册用户名是否可用
def registered_username(username):
'''
#判断注册用户名是否可用
:param username: 用户名
:return: True 可用(用户不存在) False 不可用(用户已存在)
'''
# 纯用户名列表,不包含密码
user_list = []
with open(file_name, encoding='utf-8') as f1:
for i in f1:
# 去空格,以空格切割,转换为列表
li = i.strip().split() # [张三,123]
# 将用户名追加到列表中
user_list.append(li[0])
# 判断用户名是否存在列表中
if username in user_list:
# 返回False
return False
else:
return True
6.写入用户列表文件
def write_file(username,password):
'''
#写入用户列表文件
:param username: 用户名
:param password: 密码
:return: True 写入成功 False 写入失败
'''
with open(file_name, encoding='utf-8', mode='a') as f2:
f2.write('\n{} {}'.format(username, password))
return True
7.登录逻辑
def login(count=0,max=3):
'''
登录逻辑
:param count: 初始失败次数
:param max: 最大失败次数
:return:
'''
while count < max:
count += 1
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
# 执行验证用户名和密码函数
result = username_password(username,password)
if result:
print('登陆成功\n倒计时1秒返回菜单!')
time.sleep(1)
user_menu()
break
else:
print('用户名或密码错误,还剩余{}次机会!'.format(max - count)) # 返回主菜单
user_menu()
8.判断用户名和密码是否匹配
def username_password(username,password):
'''
#判断用户名和密码是否匹配
:param username: 用户名
:param password: 密码
:return: True 匹配成功 False 匹配失败
'''
# print(username,password)
with open(file_name, encoding='utf-8', mode='r') as f3:
for i in f3:
# print(i)
# 去空格,以空格切割,转换为列表
li = i.strip().split() # [张三,123]
# 判断用户名和密码是否匹配
if username == li[0] and password == li[1]:
result = True
# 当找到匹配时,跳出循环
break
else:
result = False
# 当整个用户列表遍历完成之后,再return
return result
最终完整代码如下:
# -*- coding: utf-8 -*-
import time,os #文件名
file_name = 'user_list.txt' def file_exists(*args,**kwargs):
'''
# 判断用户列表文件是否存在
:return: True 存在 False 不存在
'''
# 判断文件是否存在
if os.path.exists(file_name):
return True
else:
with open(file_name, encoding='utf-8', mode='w') as mk:
mk.write('张三 123')
return False def registered_username(username):
'''
#判断注册用户名是否可用
:param username: 用户名
:return: True 可用(用户不存在) False 不可用(用户已存在)
'''
# 纯用户名列表,不包含密码
user_list = []
with open(file_name, encoding='utf-8') as f1:
for i in f1:
# 去空格,以空格切割,转换为列表
li = i.strip().split() # [张三,123]
# 将用户名追加到列表中
user_list.append(li[0])
# 判断用户名是否存在列表中
if username in user_list:
# 返回False
return False
else:
return True def write_file(username,password):
'''
#写入用户列表文件
:param username: 用户名
:param password: 密码
:return: True 写入成功 False 写入失败
'''
with open(file_name, encoding='utf-8', mode='a') as f2:
f2.write('\n{} {}'.format(username, password))
return True def username_password(username,password):
'''
#判断用户名和密码是否匹配
:param username: 用户名
:param password: 密码
:return: True 匹配成功 False 匹配失败
'''
# print(username,password)
with open(file_name, encoding='utf-8', mode='r') as f3:
for i in f3:
# print(i)
# 去空格,以空格切割,转换为列表
li = i.strip().split() # [张三,123]
# 判断用户名和密码是否匹配
if username == li[0] and password == li[1]:
result = True
# 当找到匹配时,跳出循环
break
else:
result = False
# 当整个用户列表遍历完成之后,再return
return result def register(*args,**kwargs):
'''
注册逻辑
:return:
'''
while True:
username = input('请输入注册的用户名,或输入q返回菜单:').strip()
if username == '':
print('用户名为空,请重新输入!')
elif username.upper() == 'Q':
break
else:
# 执行判断用户名函数
result = registered_username(username)
if result:
password = input('请输入您的注册的密码:').strip()
# 判断密码
if password == '':
print('密码为空,请重新输入!')
else:
# 执行写入用户列表文件函数
result = write_file(username, password)
if result:
print('注册成功!,您的用户名为: {}\n倒计时2秒返回菜单!'.format(username))
time.sleep(2)
user_menu()
else:
print('注册失败!请重试')
else:
print('用户名已经存在,请重新输入!') def login(count=0,max=3):
'''
登录逻辑
:param count: 初始失败次数
:param max: 最大失败次数
:return:
'''
while count < max:
count += 1
username = input('请输入用户名:').strip()
password = input('请输入密码:').strip()
# 执行验证用户名和密码函数
result = username_password(username,password)
if result:
print('登陆成功\n倒计时1秒返回菜单!')
time.sleep(1)
user_menu()
break
else:
print('用户名或密码错误,还剩余{}次机会!'.format(max - count)) # 返回主菜单
user_menu() def user_menu(*args,**kwargs):
'''
# 用户菜单
'''
# 判断文件是否存在,不存在创建文件
file_exists()
# 循环
while True:
# 打印菜单
menu = ['注册', '登录', '退出']
print('bbs系统'.center(25, '#'))
for i in range(len(menu)):
print('{}\t{}'.format(i + 1, menu[i]))
print(''.center(27, '#'))
number = input('请选择序号: ').strip()
if number == '1':
# 执行注册程序
register()
elif number == '2':
# 执行登录程序
login()
elif number == '3':
exit()
else:
print('输入错误,请重新输入!') # 执行菜单
user_menu()
执行输出:
python 全栈开发,Day11(函数名应用,闭包,装饰器初识,带参数以及带返回值的装饰器)的更多相关文章
- python全栈学习--day11(函数高级应用)
一,函数名是什么? 函数名是函数的名字,本质:变量,特殊的变量. 函数名()执行此函数 ''' 在函数的执行(调用)时:打散. *可迭代对象(str,tuple,list,dict(key))每一个元 ...
- python全栈开发笔记---------函数
一 数学定义的函数与python中的函数 初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因 ...
- python全栈开发-Day9 函数对象、函数嵌套、名称空间与作用域
一 .函数对象 一 .函数是第一类对象,即函数可以当作数据传递 可以被引用 可以当作参数传递 返回值可以是函数 可以当作容器类型的元素 二. 利用该特性,优雅的取代多分支的if def foo(): ...
- python全栈开发-前方高能-函数
python_day_9 一.今日主要内容 函数: 函数:对功能的封装 语法: def 函数名(形参): 函数体 函数名(实参) 函数名:命名规则和变量一样 函数的返回值: return, 函数执行完 ...
- python全栈开发-Day8 函数基础
python全栈开发-Day8 函数 一 .引子 1. 为何要用函数之不用函数的问题 #1.代码的组织结构不清晰,可读性差 #2.遇到重复的功能只能重复编写实现代码,代码冗余 #3.功能需要扩展时,需 ...
- python全栈开发-Day11 迭代器、生成器、面向过程编程
一. 迭代器 一 .迭代的概念 迭代器即迭代的工具,那什么是迭代呢? 迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而 ...
- python全栈开发-前方高能-函数进阶
python_day_10 一.今日主要内容 1. 动态参数 位置参数的动态参数: *args 关键字参数的动态参数 : **kwargs 顺序: 位置,*args,默认值,**kwargs 在形参上 ...
- python全栈开发_day15_函数回调和模块
一:函数回调 def a(fn=None): print("run1") if fn: fn() print("run 2") def b(): print(& ...
- python全栈开发_day10_函数的实参和形参
一:函数的实参和形参 实参是在调用函数时()出现的外界的实际的值 形参不能再函数外部直接使用 1)实参的两种形式 实参是调用函数时()中传入的参数 1.位置实参 def a(a): print(a) ...
- python 全栈开发,Day118(django事务,闭包,客户管理,教学管理,权限应用)
昨日内容回顾 一.django事务 什么是事务 一系列将要发生或正在发生的连续操作. 作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行. 事务处理可以确保除非事务性单元内的所有操 ...
随机推荐
- Hadoop基础-HDFS安全管家之Kerberos实战篇
Hadoop基础-HDFS安全管家之Kerberos实战篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们都知道hadoop有很多不同的发行版,比如:Apache Hadoop ...
- Python基础【day03】:入门知识拾遗(八)
本节内容 1.作用域 2.三元运算 3.进制 一.作用域 对于变量的作用域,执行声明并在内存中存在,该变量就可以在下面的代码中使用. 1 2 3 if 1==1: name = 'wupeiq ...
- netty基础篇
什么是Bio? 当客户端数量过多时,创建的线程会越来越多,最终服务挂掉,因为客户端的线程数量和服务端创建的线程数量是一一对应的. 什么是伪异步IO? 什么是Nio? 什么是Aio
- Spark记录-Spark on Yarn框架
一.客户端进行操作 1.根据yarnConf来初始化yarnClient,并启动yarnClient2.创建客户端Application,并获取Application的ID,进一步判断集群中的资源是否 ...
- git使用详细过程
1. Git概念 1.1. Git库中由三部分组成 Git 仓库就是那个.git 目录,其中存放的是我们所提交的文档索引内容,Git 可基于文档索引内容对其所管理的文档进行内容追踪,从而 ...
- POJ - 3122 Pie(二分)
http://poj.org/problem?id=3122 题意 主人过生日,m个人来庆生,有n块派,m+1个人(还有主人自己)分,问每个人分到的最大体积的派是多大,PS每 个人所分的派必须是在同一 ...
- 使用paramiko远程执行命令、下发文件
写部署脚本时,难免涉及到一些远程执行命令或者传输文件. 之前一直使用sh库,调用sh.ssh远程执行一些命令,sh.scp传输文件,但是实际使用中还是比较麻烦的,光是模拟用户登陆这一点,还需要单独定义 ...
- .Net进阶系列(15)-异步多线程(线程的特殊处理和深究委托赋值)(被替换)
1. 线程的异常处理 我们经常会遇到一个场景,开启了多个线程,其中一个线程报错,导致整个程序崩溃.这并不是我们想要的,我需要的结果是,其中一个线程报错,默默的记录下,其它线程正常进行,保证程序整体可以 ...
- 以前的 Delphi版本
Delphi 1 Delphi 2 Delphi 3 Delphi 4 Delphi 5 Delphi 6 Delphi 7 Delphi 8 Delphi 2005
- 发送http请求的方法
在http/1.1 协议中,定义了8种发送http请求的方法 get post options head put delete trace connect patch. 根据http协议的设计初衷,不 ...