摘要:正常情况下,会先搜索对象的属性,如果没有,再去搜索类的属性,如果属性存在,则可以调用。方法并不会立即返回一个对象实例,方法之后,会调用方法来给对象增加新的属性。转载自我的博客捕蛇者说
日常编写Python代码的过程中,特别是Python新手,经常会遇到这样的错误:
TypeError: object() takes no parameters
对于上面这个错误,很容易迷惑我们,因为这个错误信息没有很明确的指出,到底是哪段代码除了问题。那这个错误是怎么产生的了,请听我细细道来。
在python中,方法是一个属性,也就是说,当我们调用一个方法时,python需要所属方法名对应的属性,比如说:
o.m()
python会现在对象o中搜索m属性,如果对象o有m属性(判断对象o有没有m属性,可以用hasattr函数)则调用它。
然而,python的方法是定义在一个class里的,而不是object里。也就是说如果m是o的方法,那就不可能是它的属性。正常情况下,python会先搜索对象的属性,如果没有,再去搜索类的属性,如果属性存在,则可以调用。(这地方可能大家会被类和对象两个概念搞混,不太准确的来说,类就是class,对象就是实例,具体大家可以查看文章笨办法学Python)
在python中,大多数的类都继承自object,在Python3中,如果你没有指定继承object,解释器会自动给你加上,而Python如果你没有指定,则为old-style class。大家在平时编写类时,建议大家都最好加上继承object,这样一个是代码兼容性号,一个是比较优雅。
如果属性在对象里不存在,我们会得到一个错误信息,指明了哪个地方的代码有问题和出问题的原因,但是和我们上面说的错误
TypeError: object() takes no parameters
这个错误是我在创建对象实例时报的错误,例如:
class Foo(object): pass
如果我这样:
f = Foo()
就不会有任何问题,但是如果我这样:
f = Foo(10)
然后我就会得到上面的错误,这究竟是为什么了?
这是因为Python在创建对象是,分为两个阶段:第一个阶段,对象是通过调用__new__方法来创建的,这个方法的细节我们基本上不用关心。__new__方法并不会立即返回一个对象实例,__new__方法之后,会调用__init__方法来给对象增加新的属性。对于上面的对象o,调用的就是
o.__init__()
Python首先查找o的__init__方法,但是没找到,然后查找父类的__init__方法,假设父类是上面的Foo,可以方式__init__方法依然不存在,所以最后会找到object的__init__属性。object的__init__是存在的,并且是个方法,然后调用这个方法,传入相应的参数,但是object.__init__方法没有参数,然后我们就得到的上面的错误。
TypeError: object() takes no parameters
整个流程下来,最让人迷惑的地方是,Python没有这样报错:
“object.__init__()” takes no parameters
于是我们没法定为这个问题出在哪。
总结下来,在实现一个python的类时,最后写上__init__方法,这样就可以避免这样的迷惑性的错误。
转载自我的博客捕蛇者说文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/40915.html
摘要:本篇主要总结中绑定方法对象和未绑定方法对象的区别和联系。在中使用描述器有翻译的链接来表示具有绑定行为的对象属性,使用描述器协议方法来控制对具有绑定行为属性的访问,这些描述器协议方法包括和。其中通过限定的必须使用实例才能调用。 本篇主要总结Python中绑定方法对象(Bound method object)和未绑定方法对象(Unboud method object)的区别和联系。主要目的...
摘要:并且集合中的元素也是随机排序的。除了用来创建集合,还可以使用的方式,但是这种方式不提倡使用,因为在某些情况下,搞不清楚是字典还是集合。集合不是序列类型,不能用索引方式对其进行修改和实现集合和列表两种对象之间的转化。 集合Set类似字典的特点,可以用{}花括号来定义;其中的元素是没有序列,也就是非序列类型的数据;而且集合中的元素不可重复,这就类似于dict键。 创建集合 >>> s1 =...
摘要:中,引入了其他很多语言都具备的模式匹配和默认参数语法糖,使得代码简洁了不少。模式匹配中需要注意的触发默认值如下所示右侧的元素会触发左侧的默认值。 ES6 中,引入了其他很多语言都具备的模式匹配和默认参数语法糖,使得代码简洁了不少。但是使用的时候还是有些细节需要注意。 模式匹配原理 模式匹配的种类 具体来说,有三种类型的模式匹配: 直接赋值 let a = 1; 对象模式 let...
摘要:中的类都是单例模式一天,一同事问我这样一个问题。与方法属于新式类,即属于类。方法在实例被创建之后被调用,该方法仅仅是对方法创建的实例进行一些初始化操作。需要注意的是,在重写方法与方法的参数应该保持一致,否则会有发生。 Python 中的类都是单例模式? 一天,一同事问我这样一个问题。这是一个奇怪的问题,可能你也这么认为。这里先不做解释,我们先来看看 __new__ 和 __init__...
以下是严格模式中需要注意的用法,这里需要强调的是:ES6 的 class 和 模块内都是默认的严格模式。其实,js 开发也会逐步走向严格模式,这应该是个趋势。 添加了保留字 protected,static 和 interface 在严格模式下,不可以用with() (function(){ //非严格模式 var a = {name: Bob}; with(a){ name ...
阅读 3262·2023-04-25 14:35
阅读 3417·2021-11-15 18:00
阅读 2535·2021-11-12 10:34
阅读 2481·2021-11-11 16:54
阅读 3463·2021-10-08 10:12
阅读 2761·2021-09-06 15:02
阅读 3317·2021-09-04 16:48
阅读 2798·2019-08-29 14:02