【问题标题】:Different behaviour in Instantiation of class in PythonPython中类实例化的不同行为
【发布时间】:2018-10-02 15:26:27
【问题描述】:

最近我一直在尝试类和对象,并陷入了一个疑问。我试过谷歌搜索,但我不明白要搜索什么。下面是代码sn-p。

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

【问题讨论】:

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


    【解决方案1】:

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

    你自己展示了这个:

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

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

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

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

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

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

    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了解更多信息

    【讨论】:

    • 所以它更像是为Demo类对象创建一个别名..?
    • @DibakarBose 是的。 Python 中的每个 赋值就像创建一个别名。请注意,类对象是 Python 中的一等公民。就像函数一样,它们可以分配给变量,重新分配给任何其他变量,作为函数参数传递,从函数返回等
    • 我明白了.. 现在我明白了.. 谢谢
    • @DibakarBose 我更新了一些你可能会觉得有启发性的信息
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    • 2021-07-18
    • 2023-04-08
    • 1970-01-01
    • 2014-12-13
    • 2011-01-01
    • 2022-10-25
    相关资源
    最近更新 更多