Python 中 class 实例化的不同行为

Different behaviour in Instantiation of class in Python

最近我一直在尝试 类 和对象,但遇到了一个疑问。我尝试使用谷歌搜索,但我不明白要搜索什么。下面是代码片段。

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

a=Demo 不创建任何对象,它只是将 Demo class 对象分配给变量 a.

你居然自己展示了这个:

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

在 Python 中,classes 也是具有 type.

类型的对象

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

请注意,classes 是第一个 class 对象,您可以像对待任何其他对象一样对待它们,例如 listinttype 实际上只是一个构造函数,就像 listint:

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

类型构造函数接受三个参数,即 class 的名称作为字符串(注意,您没有 将其分配给相同的变量名称) ,一个基元组,这里是空的,所以它是隐含的 object,就像你做 class A: pass 命名空间 ,所以从属性名称到属性。方法只是属于 class

命名空间的函数对象
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

下面是一个 class 使用 type 构造函数创建的稍微不那么简单的示例,该构造函数也有方法:

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

docs

中阅读更多内容