Python 实例化类-带括号和不带括号之间的区别

Python 实例化类-带括号和不带括号之间的区别,python,python-2.7,Python,Python 2.7,经过很长一段时间之后,我想回顾一下Python,并更新一些概念,我希望这个问题不是一个坏问题 假设我有一个非常简单的类,如下所示: class myClass: def __init__(self): self.myProp = 2 如果我使用括号来实例化,一切都会按照我的预期进行: >>> a = myClass() >>> a.myProp 2 但是,如果我不使用上面两行的括号,即: >>> a = myCl

经过很长一段时间之后,我想回顾一下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
是类的一个实例,但不知何故没有初始化。 在其他语言中,如果试图在不初始化的情况下将类实例强制转换为对象,则可能会出现编译错误(例如,在C中,
myClass a=new-myClass();
可以正常工作,但
myClass a=new-myClass;
将返回编译错误)


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

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
s,但这仍然是在运行时


1没有双关语

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

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

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

>类R:pass#在Python 2中,需要类R(对象):pass
>>>r=r()
现在我们有两个变量,
R
R
r
是类
r
的一个实例。这里的技巧是
R
是类
type
的一个实例,这就是为什么我们称
R
为类的原因。
r
r
都是
object
的实例,这就是为什么我们称它们为object。而
R
是类
object
的一个子类,因为
R
是一个类

>isinstance(R,类型)
真的
>>>isinstance(r,r)
真的
>>>issubclass(R,对象)
真的
>>>isinstance(r,对象)
真的
>>>isinstance(类型、对象)
真的
>>>isinstance(类型,类型)
真的
每个Python对象都是
对象
的实例,每个Python类都是
对象
的子类,每个Python类都是
类型
的实例


请注意,我所说的在Python3和Python2的“新样式”类中是正确的。不要关心Python老式类。

不,它不是类的实例,而是类对象本身。这对我来说很有意义,因为它肯定回答了我的问题,我会尽快接受它(因此我仍然禁止)。但我要借此机会问:有用的一面是什么?我的意思是,为什么我要把一个类转换成一个变量?我问这个问题是因为我想象不清楚,希望通过一个简单的解释性例子来了解它。@MatteoNNZ-你不会“将一个类强制转换成一个对象”;类是Python中的对象,包括函数、方法甚至文字在内的所有其他对象都是对象。至于为什么要传递一个类对象作为一个参数,考虑一个例子,使用<代码> map < /Cl>:<代码> map(STR,[1, 2, 3)] <代码>代码> STR >是一个类对象,例如“代码> MyClass < /Class >,并且在这种情况下,使用一个整数列表来构建<代码> STR < /Cl>实例。涉及将一个变量设置为一个类。实际上,类的名称只是另一个变量。
MyClass
没有什么特别之处,而
a
则没有。我一直在使用这个功能,例如,我可以创建几个类,它们都为同一个问题实现不同的算法,并且可以将函数传递给我想要执行计算的类,这样函数就可以专注于收集输入和输出。感谢您对@iCodez和wkswartz的解释,事情更清楚了。
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)
>>> a = myClass
>>> a
<class __main__.myClass at 0x10cd1de20>
>>> b = myClass()
>>> b
<__main__.myClass instance at 0x10cd8efc8>