Python类实例化中的不同行为

时间:2018-10-02 15:26:28

标签: python python-3.x class object instance

最近,我一直在尝试类和对象,并陷入一个疑问。我尝试使用Google搜索,但是不知道该搜索什么。下面是代码段。

class Demo:
    def __init__(self):
        print("In init")

    def __call__(self,item):
        print("Got {} in call".format(item))

    def print(self):
        print("Evaluating print()")

现在完成上述程序后,我尝试了以下一些命令,如下所示:

>>>a=Demo
>>>a.print()
Traceback (most recent call last):
  Python Shell, prompt 3, line 1
builtins.TypeError: print() missing 1 required positional argument: 'self'
>>>a.print(a)
Evaluating print()
>>>b=Demo()
In init
>>>b.print()
Evaluating print()
>>>type(a)
<class 'type'>
>>>type(b)
<class '__main__.Demo'>

在这种情况下,我的问题是:
1)创建对象时a=Demob=Demo()有什么区别?
2)为什么a.print()在第一种情况下不起作用,但是a.print(a)可以正常工作吗?
3)在这种情况下,b('item')将以Got item on call的形式给出输出,而在a('item')的情况下则无效。为什么会这样呢?

注意::我正在为此使用Python 3.6

1 个答案:

答案 0 :(得分:2)

a=Demo不创建任何对象,仅将Demo类对象分配给变量a

您实际上亲自展示了此内容:

>>>type(a)
<class 'type'>
>>>type(b)
<class '__main__.Demo'>

在Python中,类也是类型为type的对象。

通过将a替换为a,比较使用Demo时发生的情况。

请注意,类是一流的对象,您可以将它们像其他任何对象一样对待,例如listinttype实际上只是一个构造函数,例如listint

>>> list()
[]
>>> int()
0
>>>
>>> MyClass = type('MyClass', (), {})
>>> MyClass
<class '__main__.MyClass'>
>>> MyClass()
<__main__.MyClass object at 0x10406fe80>
>>>

类型构造函数以类的名称作为字符串的三个参数(注意,您没有必须将其分配给相同的变量名称),一个基元组,这里是空的因此它隐式地是object,就像您做过class A: pass一样,还有 namespace ,因此是从属性名称到属性的映射。方法只是属于类名称空间的函数对象

Init signature: type(self, /, *args, **kwargs)
Docstring:
type(object_or_name, bases, dict)
type(object) -> the object's type
type(name, bases, dict) -> a new type
Type:           type

这是使用type构造函数创建的类的平凡例子,该构造函数还具有方法:

>>> Foo = type('Foo', (), {'__init__': lambda self, x: setattr(self, 'x', x), 'bar': lambda self: self.x})
>>> f = Foo(42)
>>> f.bar()
42

docs

中了解更多信息