前言
翻出之前做个压测项,看到locust中对等待时间的实现方式感到好奇,于是总结下来。
源代码实现
def between(min_wait, max_wait):
"""
Returns a function that will return a random number between min_wait and max_wait.
Example::
class MyUser(User):
# wait between 3.0 and 10.5 seconds after each task
wait_time = between(3.0, 10.5)
"""
return lambda instance: min_wait + random.random() * (max_wait - min_wait)
def constant(wait_time):
"""
Returns a function that just returns the number specified by the wait_time argument
Example::
class MyUser(User):
wait_time = constant(3)
"""
return lambda instance: wait_time
可以看到locust中对等待时间的处理是先返回一个匿名函数,然后在一个类中 wait_time = constant(3),再在task类中调用wait_time()返回一个具体的等待时间
def wait(self):
"""
Make the running user sleep for a duration defined by the Locust.wait_time
function (or TaskSet.wait_time function if it's been defined).
The user can also be killed gracefully while it's sleeping, so calling this
method within a task makes it possible for a user to be killed mid-task, even if you've
set a stop_timeout. If this behaviour is not desired you should make the user wait using
gevent.sleep() instead.
"""
if self.user._state == LOCUST_STATE_STOPPING:
raise StopUser()
self.user._state = LOCUST_STATE_WAITING
self._sleep(self.wait_time())
if self.user._state == LOCUST_STATE_STOPPING:
raise StopUser()
self.user._state = LOCUST_STATE_RUNNING
def _sleep(self, seconds):
gevent.sleep(seconds)
写法的原理探究
我们先自己仿写一下代码
def call_fuc():
return lambda x: print(x)
class User:
x = call_fuc()
u = User()
u.x()
看到当我们执行的时候,就会执行返回的匿名函数的逻辑打印一个类对象
拆解函数
对于不熟悉lambda函数的人来说理解这段函数可能有点绕,所以我们拆解一下
def call_fuc():
# return lambda x: print(x)
def lam(x):
print(x)
在上面可以看到返回了一个函数给类属性所以x = call_fuc(),x就成了一个方法了,方法接收一个形参x,接收一个参数x,又是在类里面,这不是就是成了一个实例方法吗,在类里面我们约定俗成把第一个参数叫做self,但是Python本身没有对命名做要求所以在这里x = self。重新定义一个实例方法
class User:
x = call_fuc()
def lam(x):
print(x)
u = User()
u.lam()
u.x()
输出结果