最近,我一直在尝试类和对象,并陷入一个疑问。我尝试使用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=Demo
和b=Demo()
有什么区别?
2)为什么a.print()
在第一种情况下不起作用,但是a.print(a)
可以正常工作吗?
3)在这种情况下,b('item')
将以Got item on call
的形式给出输出,而在a('item')
的情况下则无效。为什么会这样呢?
注意::我正在为此使用Python 3.6
答案 0 :(得分:2)
a=Demo
不创建任何对象,仅将Demo
类对象分配给变量a
。
您实际上亲自展示了此内容:
>>>type(a)
<class 'type'>
>>>type(b)
<class '__main__.Demo'>
在Python中,类也是类型为type
的对象。
通过将a
替换为a
,比较使用Demo
时发生的情况。
请注意,类是一流的对象,您可以将它们像其他任何对象一样对待,例如list
或int
。 type
实际上只是一个构造函数,例如list
和int
:
>>> 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
中了解更多信息