实例化课程 - 有和没有括号之间的区别

时间:2015-02-03 22:12:23

标签: python python-2.7

在很长一段时间内收回Python并希望刷新一些概念,我希望这个问题不错。

说我有一个非常简单的类,如下所示:

class myClass:
    def __init__(self): 
        self.myProp = 2

如果我使用括号实例化,一切都按预期工作:

>>> a = myClass()
>>> a.myProp
2

但是,如果我不在上面两行使用括号,即:

>>> a = myClass

我收到以下错误:

>>> a.myProp
Traceback (most recent call last):
File "<pyshell#45>", line 1, in <module>
a.myProp
AttributeError: class myClass has no attribute 'myProp'

如果我打印对象,

>>> a = myClass
>>> a

我得到了

<class __main__.myClass at 0x0275C538>

似乎a是该类的一个实例,但不知何故未初始化。 在其他语言中,如果尝试将类实例强制转换为对象而不进行初始化(例如在C#中,myClass a = new myClass();将正常工作但myClass a = new myClass;将返回编译错误),我会期望编译错误。

所以我的问题是:从技术上讲,什么是没有括号的对象a = myClass

3 个答案:

答案 0 :(得分:7)

a是类本身 - 在python中,类是第一类对象 1 。您可以将它们作为参数传递,将它们别名为不同的名称(就像您在示例中所做的那样),然后您可以使用当前命名空间中的任何引用实例。

a = myClass  # a and myClass identical at this point.  The interpretter won't care which you use.
a_instance = a()  # instance of myClass

def make_instance(cls):
    return cls()

another_instance = make_instance(a)
yet_another_instance = make_instance(myClass)

你看,python没有任何“编译时检查”,因为真的 - 没有编译时间。 Python代码在运行时处解释。是的,您可以在导入时弹出SyntaxError,但这仍然是在运行时。

1 没有双关语

答案 1 :(得分:6)

它是对类本身的引用,而不是对类实例的引用。请注意区别:

>>> a = myClass
>>> a
<class __main__.myClass at 0x10cd1de20>
>>> b = myClass()
>>> b
<__main__.myClass instance at 0x10cd8efc8>

答案 2 :(得分:3)

Python中的所有内容都是一个对象,因此是一个类的实例,包括类。操作类或将它们作为变量传递没有什么特别之处。因此,引用同一对象的变量aMyClass只是MyClass的对象。

>>> class R: pass # In Python 2, you would need class R(object): pass
>>> r = R()

现在我们有两个变量Rrr是类R的一个实例。这里的诀窍是R是类type的一个实例,这就是我们将R称为类的原因。 rR都是object的实例,这就是我们将它们都称为对象的原因。 R是类object的子类,因为R是一个类。

>>> isinstance(R, type)
True
>>> isinstance(r, R)
True
>>> issubclass(R, object)
True
>>> isinstance(r, object)
True
>>> isinstance(type, object)
True
>>> isinstance(type, type)
True

每个Python对象都是object的实例,每个Python类都是object的子类,每个Python类都是type的实例。

请注意,我所说的在Python 3和Python 2“新风格”类中都是正确的。不要关心Python旧式类。