Различное поведение в реализации класса в Python - PullRequest
0 голосов
/ 02 октября 2018

Недавно я экспериментировал с классами и объектами и застрял в одном сомнении.Я попробовал поискать в Google, но я не понял, что искать.Ниже приведен фрагмент кода.

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=Demo и b=Demo() при создании объектов?
2) Почему a.print() не работал в первом случае, но a.print(a) работает нормально?
3) В этом случаеb('item') будет работать, чтобы выдать вывод как Got item on call, который не работает в случае a('item').Почему это так?

ПРИМЕЧАНИЕ :: Я использую Python 3.6 для этого

1 Ответ

0 голосов
/ 02 октября 2018

a=Demo не создает никаких объектов, он просто присваивает объект класса Demo переменной a.

Вы фактически показываете это сами:

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

В Python классы также являются объектами типа type.

Сравните, что происходит при использовании a, заменив a на Demo.

Обратите внимание, что классыПервоклассные объекты, вы можете обращаться с ними как с любым другим объектом, например с list или int.type на самом деле просто конструктор, как list и int:

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

Подробнее в документах

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...