当前位置: 首页 > news >正文

内蒙古手机网站制作/苏州seo培训

内蒙古手机网站制作,苏州seo培训,太仓新网站优化,官网seo关键词排名系统可以调用的对象 关于 __call__ 方法,不得不先提到一个概念,就是可调用对象(callable),我们平时自定义的函数、内置函数和类都属于可调用对象,但凡是可以把一对括号()应用到某个对象身上都可称之为可调用对…

可以调用的对象

关于 __call__ 方法,不得不先提到一个概念,就是可调用对象(callable),我们平时自定义的函数、内置函数和类都属于可调用对象,但凡是可以把一对括号()应用到某个对象身上都可称之为可调用对象,判断对象是否为可调用对象可以用函数 callable

如果在类中实现了 __call__ 方法,那么实例对象也将成为一个可调用对象,

你也许已经知道,在Python中,方法也是一种高等的对象。这意味着他们也可以被传递到方法中就像其他对象一样。这是一个非常惊人的特性。 在Python中,一个特殊的魔术方法可以让类的实例的行为表现的像函数一样,你可以调用他们,将一个函数当做一个参数传到另外一个函数中等等。这是一个非常强大的特性让Python编程更加舒适甜美。 __call__(self, [args...])

允许一个类的实例像函数一样被调用。实质上说,这意味着 x() 与 x.__call__() 是相同的。注意 __call__ 参数可变。这意味着你可以定义 __call__ 为其他你想要的函数,无论有多少个参数。

__call__ 在那些类的实例经常改变状态的时候会非常有效。调用这个实例是一种改变这个对象状态的直接和优雅的做法。用一个实例来表达最好不过了:

class Entity:
'''调用实体来改变实体的位置。'''def __init__(self, size, x, y):self.x, self.y = x, yself.size = sizedef __call__(self, x, y):'''改变实体的位置'''self.x, self.y = x, ye = Entity(1, 2, 3) // 创建实例
e(4, 5) //实例可以象函数那样执行,并传入x y值,修改对象的x y 

实例 --- Flask Wtform

在wtform的validators就使用了这个特性
wtform 定义字段的时候可以为每个字段添加校验器, 而每个校验器的特点都是接受两个参数,form, field。
所以我们可以自己自定义校验器,校验器是可调用对象即可,即函数,对象方法,都可以的。
比如function url_validate(form, field)

使用函数定制

下面提供一个my_length_check()函数,用于验证name长达是否长于50个字符。
这个函数按照规定接受两个参数,form, field,然后就可以根据两个参数进行判断。
这样做是可以的,但是问题是:如果我想自定义错误信息怎么办?而且我想限制的数量也能控制,不是写死, 还有如果有最小值,和最大值呢? 这里只能固定接受两个参数,不能再传入自定参数,没得更多的自定义了,这样就会限制住了。

def my_length_check(form, field):if len(field.data) > 50:raise ValidationError('Field must be less than 50 characters')class MyForm(Form):name = StringField('Name', [InputRequired(), my_length_check])

使用闭包和工厂模式

为了解决上面能传入更多自定义参数, 更灵活定制校验,我们进行改造。
使用工厂模式,一个能生产校验器的工厂,而这个工厂能接受其他更灵活的参数,看例子:

def length(min=-1, max=-1, message=None):if not message:message = 'Must be between %d and %d characters long.' % (min, max)def _length(form, field):l = field.data and len(field.data) or 0if l < min or max != -1 and l > max:raise ValidationError(message)return _lengthclass MyForm(Form):name = StringField('Name', [InputRequired(), length(max=50)])

这里涉及两个概念:

  • 工厂模式
    这个例子的length()是一个工厂,他的工作就是执行的时候,生产一个validator校验器,每次调用,传入不同参数,就会生产不同的校验器,所以叫做工厂模式。

  • 闭包
    同时它也是个闭包, 为什么是个闭包?正常情况下执行完length() min, max, message参数就会被回收,不在存在,但是为什么_length()能继续读取min, max, message变量,就是闭包的威力。闭包使得局部变量在函数外被访问成为可能。
    这里的 length() 就是一个闭包,闭包本质上是一个函数,它有两部分组成,_length 函数和变量 min, max, message。闭包使得这些变量的值始终保存在内存中。
    参考:一步一步教你认识Python闭包

这个length(min, max, message) 函数,调用的时候,传入了更多的参数来灵活决定校验器,因为他里面就是返回一个_length的校验器,这个校验器还是遵循规则,只接受form, field 参数, 但是在length() 这个外层却能接受更多参数,而这些参数也能被内层的_length()所使用。

class MyForm(Form):name = StringField('Name', [InputRequired(), length(max=50)])

这里的length(max=5)就是返回了个_length函数,wtform调用校验器的时候实际上就是这样调用的:

length(max=50)(form, field)

使用类方法__call__实现

class Length(object):def __init__(self, min=-1, max=-1, message=None):self.min = minself.max = maxif not message:message = u'Field must be between %i and %i characters long.' % (min, max)self.message = messagedef __call__(self, form, field):l = field.data and len(field.data) or 0if l < self.min or self.max != -1 and l > self.max:raise ValidationError(self.message)class MyForm(Form):name = StringField('Name', [InputRequired(), Length(max=50)])

这次我们使用类来实现,首先实例化这个校验器Length(max=50), 这时返回的是对象实例,然后我们定义了方法__call__方法,说明实例对象是可以调用的, 最后的结果就是Length(max=50)(form, field)。
这样实现方法是也是很妙的。
说到这里,类实现方法跟闭包很像,都是把变量封装起来,让真正的校验器能读取到参数。

闭包避免了使用全局变量,此外,闭包允许将函数与其所操作的某些数据(环境)关连起来。这一点与面向对象编程是非常类似的,在面对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。

__call__其他作用

实例对象也可以像函数一样作为可调用对象来用,那么,这个特点在什么场景用得上呢?这个要结合类的特性来说,类可以记录数据(属性),而函数不行(闭包某种意义上也可行),利用这种特性可以实现基于类的装饰器,在类里面记录状态,比如,下面这个例子用于记录函数被调用的次数:

class Counter:def __init__(self, func):self.func = funcself.count = 0def __call__(self, *args, **kwargs):self.count += 1return self.func(*args, **kwargs)@Counter
def foo():passfor i in range(10):foo()print(foo.count)  # 10

首先这里的@Counter是装饰器,执行起来顺序是 foo = Counter(foo), 实例化,把foo函数传到类Counter里面,并存到对象属性里面,然后返回foo = Counter实例。 这时foo已经是Counter实例,而不是本身foo函数。
当执行foo()的时候,其实已经变成了,执行__call__函数,而这个函数里面是执行了本身的self.func 即foo的实际逻辑, 而且加上了计算调用次数。这样就记录状态了。
太厉害了,这样的实现方式。

https://wtforms.readthedocs.io/en/stable/validators.html#custom-validators
https://stackoverflow.com/questions/9663562/what-is-the-difference-between-init-and-call-in-python
一步一步教你认识Python闭包
简述 initnewcall 方法



 

http://www.lbrq.cn/news/754651.html

相关文章:

  • 深圳网站设计价格表/超能搜索引擎系统网站
  • 自己做的网站怎么才能被收录/河北网络科技有限公司
  • 做网站选云服务器内核/网站推广的全过程
  • 深圳市土方建设网站/运营培训班
  • 商洛做网站多少钱/长沙seo排名优化公司
  • 网站建设面试对策/深圳seo外包
  • 淘宝客做连接网站吗/长春百度推广公司
  • 网站维护怎么收费/seo成都培训
  • 网站推广的最终目的是什么/搜狗引擎
  • 任丘网站制作公司/自媒体平台注册入口官网
  • 专业做网站平台/吉林seo技术交流
  • 网络建站东北/网站 软件
  • 可以通过哪些网站注册域名/关键词优化上海
  • 网站开发培训机构/成都网站建设方案推广
  • 网站建设优化的作用/企业seo推广
  • 找合伙人的网站做淘宝/中国做网站的公司排名
  • 太原网站建设电话/百度搜索引擎优化详解
  • WordPress推荐版本/长沙网站seo方法
  • 杭州网站建设公司哪家好/seo资源咨询
  • 桥南做网站/企业建站用什么好
  • 济宁做网站的公司/网络营销公司好不好
  • 建设网站实施条件/个人永久免费自助建站
  • 怎么制作手机网站/qq群推广链接
  • 做网站建设要学多久/福州百度seo排名软件
  • 网站开发续签/刚刚刚刚刚刚刚刚刚刚刚刚刚刚刚
  • 网站开发组/石家庄网站建设培训
  • 网站内容/网络推广渠道和方法
  • 单产品网站建设/互联网营销方案
  • 咸宁网站建设/网络推广运营优化
  • 免费建网站的网站/广东河源最新疫情
  • 模型训练监控:TensorBoard与Weights Biases (WB) 使用详解
  • FPGA串口通信实现方案
  • Trae中`settings.json`文件的Java配置项功能详解(一)
  • DAY 46 通道注意力(SE注意力)
  • 以下是对智能电梯控制系统功能及系统云端平台设计要点的详细分析,结合用户提供的梯控系统网络架构设计和系统软硬件组成,分点论述并补充关键要点:
  • YOLOv8目标检测网络结构理论