Что под самими классами подразумеваются объекты? - PullRequest
12 голосов
/ 26 июня 2011

Я только что прочитал о документации классов Python, в которой написано, что "сами классы являются объектами". Чем это отличается от классов C # или Java?Какие преимущества и недостатки этот тип классов по сравнению с C # или Java?

Ответы [ 7 ]

8 голосов
/ 26 июня 2011

В 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
3 голосов
/ 26 июня 2011

Объявление класса - это просто объявление переменной:

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 голосов
/ 26 июня 2011

В C # и Java классы не являются объектами. Они являются типами в том смысле, в каком эти языки статически типизированы. Правда, вы можете получить объект, представляющий определенный класс, но это не то же самое, что сам класс.

В python то, что выглядит как класс, на самом деле тоже объект.

Это exlpained здесь намного лучше, чем я могу когда-либо сделать :)

1 голос
/ 28 июня 2011

Поскольку этот вопрос имеет тег 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, не требуя перекомпиляции или перезапуска виртуальной машины:

Point addInstVarName: 'z'.

Лучшее прочтение на эту тему - Искусство протокола метаобъекта .

1 голос
/ 26 июня 2011

Другое преимущество классов, являющихся объектами, состоит в том, что объекты могут изменять свой класс во время выполнения:

>>> 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__.

1 голос
/ 26 июня 2011

Классы являются объектами в том смысле, что ими можно манипулировать в коде 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 #, которые требуют, чтобы такое поведение было реализовано по-другому.

Наконец, классы, как и любой объект, создаются из классов. Как объект создается из класса, так и класс создается из специального класса, называемого метаклассом . Вы можете написать свои собственные метаклассы, чтобы изменить способ определения классов.

1 голос
/ 26 июня 2011

Основное отличие состоит в том, что они означают, что вы можете легко манипулировать классом как объектом. Та же возможность доступна в Java, где вы можете использовать методы Class , чтобы получить информацию о классе объекта. В таких языках, как Python, Ruby и Smalltalk, более динамичная природа языка позволяет «открывать» класс и изменять его, что иногда называют «исправлением обезьян».

Лично я не думаю, что различия настолько значительны, но я уверен, что мы можем начать хорошую религиозную войну из-за этого.

...