类本身的意思是对象?

时间:2011-06-26 04:50:35

标签: c# java python ruby smalltalk

我只是阅读python类文档,它说,在python“类本身就是对象”。如何与C#或Java类不同? 这类类与C#或Java相比有哪些优缺点?

7 个答案:

答案 0 :(得分:8)

在Python中,类是对象,您可以将它们分配给变量,将它们传递给函数等,就像任何其他对象一样。例如

>>> t = type(10)
>>> t
<type 'int'>
>>> len(t.__dict__)
55
>>> t() # construct an int
0
>>> t(10)
10

Java有Class个对象,它们提供有关类的一些信息,但您不能使用它们来代替显式类名。它们不是真正的类,只是类信息结构。

Class C = x.getClass();
new C(); // won't work

答案 1 :(得分:3)

声明一个类只是声明一个变量:

class foo(object):
    def bar(self): pass
print foo # <class '__main__.foo'>

可以像任何变量一样分配和存储它们:

class foo(object):
    pass
class bar(object):
    pass
baz = bar # simple variable assignment
items = [foo, bar]
my_foo = items[0]() # creates a foo
for x in (foo, bar): # create one of each type
    print x()

并作为变量传递:

class foo(object):
    def __init__(self):
        print "created foo"
def func(f):
    f()

func(foo)

它们可以由函数创建,包括基类列表:

def func(base_class, var):
    class cls(base_class):
        def g(self):
            print var
    return cls

class my_base(object):
    def f(self): print "hello"

new_class = func(my_base, 10)
obj = new_class()
obj.f() # hello
obj.g() # 10

相比之下,Java中的类具有表示它们的对象,例如。 String.class,类名本身 - String - 不是一个对象,不能作为一个对象操作。这是静态类型语言所固有的。

答案 2 :(得分:2)

在C#和Java中,类不是对象。它们是类型,在某种意义上,这些语言是静态类型的。确实,您可以获得一个表示特定类的对象 - 但这与类本身不同。

在python中看起来像一个类实际上也是一个对象。

它比我能做的更好here:)

答案 3 :(得分:1)

主要区别在于它们意味着您可以轻松地将类作为对象进行操作。 Java中提供了相同的工具,您可以使用Class的方法获取有关对象类的信息。在Python,Ruby和Smalltalk等语言中,语言更具动态性使您可以“打开”类并更改它,有时也称为“猴子修补”。

就我个人而言,我认为这些差异并不是什么大不了的事,但我相信我们可以开始就此展开良好的宗教战争。

答案 4 :(得分:1)

类是对象,因为它们可以像任何对象一样在Python代码中操作。其他人已经展示了如何将它们传递给函数,允许它们像任何对象一样进行操作。您可以通过以下方式执行此操作:

class Foo(object):
    pass

f = Foo()

f.a = "a"    # assigns attribute on instance f
Foo.b = "b"  # assigns attribute on class Foo, and thus on all instances including f

print f.a, f.b

其次,与所有对象一样,类在运行时被实例化。也就是说,类定义是执行的代码,而不是在任何运行之前编译的结构。这意味着类可以“烘焙”仅在程序运行时已知的事物,例如环境变量或用户输入。这些在声明类时被评估一次,然后成为类的一部分。这与C#等编译语言不同,后者要求以不同方式实现此类行为。

最后,类与任何对象一样,都是从类构建的。就像一个对象是从一个类构建的那样,一个类是由一种叫做元类的特殊类构建的。你可以编写自己的元类来改变类的定义方式。

答案 5 :(得分:1)

作为对象的类的另一个优点是对象可以在运行时更改它们的类:

>>> class MyClass(object):
...     def foo(self):
...         print "Yo There! I'm a MyCLass-Object!"
...
>>> class YourClass(object):
...     def foo(self):
...         print "Guess what?! I'm a YourClass-Object!"
...
>>> o = MyClass()
>>> o.foo()
Yo There! I'm a MyCLass-Object!
>>> o.__class__ = YourClass
>>> o.foo()
Guess what?! I'm a YourClass-Object!

对象具有特殊属性__class__,指向它们是实例的类。这是可能的,因为类本身就是对象,因此可以绑定到__class__之类的属性。

答案 6 :(得分:1)

由于这个问题有一个Smalltalk标签,这个答案来自Smalltalk的观点。在面向对象的编程中,事情通过消息传递完成。您向对象发送消息,如果对象理解该消息,它将执行相应的方法并返回一个值。但是,首先如何创建对象?如果引入特殊语法来创建将基于消息传递破坏简单语法的对象。这就是像Java这样的语言:

p = new Point(10, 20); // Creates a new Point object with the help of a special keyword - new.
p.draw(); // Sends the message `draw` to the Point object.

从上面的代码可以看出,语言有两种方法可以完成任务 - 一种是命令式的,另一种是面向对象的。相比之下,Smalltalk只有基于消息传递的一致语法:

p := Point new: 10 y: 20.
p draw.

此处new是发送给名为Point的单个对象的消息,该对象是Metaclass的实例。除了为语言提供一致的计算模型外,元类还允许动态修改类。例如,以下语句将向Point类添加新的实例变量,而无需重新编译或重新启动VM:

Point addInstVarName: 'z'.

关于此主题的最佳读物是The Art of the Metaobject Protocol