前言
翻出之前做个压测项,看到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 taskwait_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 argumentExample::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_timefunction (or TaskSet.wait_time function if it's been defined).The user can also be killed gracefully while it's sleeping, so calling thismethod within a task makes it possible for a user to be killed mid-task, even if you'veset a stop_timeout. If this behaviour is not desired you should make the user wait usinggevent.sleep() instead."""if self.user._state == LOCUST_STATE_STOPPING:raise StopUser()self.user._state = LOCUST_STATE_WAITINGself._sleep(self.wait_time())if self.user._state == LOCUST_STATE_STOPPING:raise StopUser()self.user._state = LOCUST_STATE_RUNNINGdef _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()
输出结果