Ответ 1
Это ничего особенного, просто для некоторых типов существует "пустой" объект по умолчанию этого типа, а для других - нет. Ваши рабочие примеры в основном эквивалентны:
int()
dict()
list()
float()
str()
complex()
tuple()
., все из которых работают. Ваши последние три примера в основном пытаются создать новые экземпляры NoneType, function
и type
.
- NoneType завершается с ошибкой по уникальной причине, потому что None - это singleton. Тип NoneType может иметь только один экземпляр, а именно объект None. (Особое сообщение об ошибке, которое вы получаете, немного странно, но если вы сделаете
types.NoneType()
, вы получите более прямое сообщение с сообщением "Невозможно создать экземпляры NoneType".) -
function
не работает, потому что, как вы видели, для этого требуется аргумент, и вы его не предоставляете. Вам понадобится объект кода, который вы можете получить из существующей функции или из функцииcompile
. (Для этого также требуется аргументglobals
, который может быть просто dict.) -
type
терпит неудачу, потому что вы не дали достаточно аргументов. Вы можете либо сделатьtype(foo)
, чтобы получить тип foo, либоtype(name, bases, dict)
, чтобы создать новый тип (т.е. Класс).
Обратите внимание, что в последнем примере вы берете тип object
, который сам по себе является типом. Если вместо этого вы сделаете x = object()
(сделав x отдельным объектом, а не типом объекта), то он будет работать и создать "пустой" объект.
Следует помнить, что вызов __new__
на самом деле не волшебный. Именно это происходит, когда вы пытаетесь создать экземпляр типа, делая someType()
. Если этот тип требует аргументов, вызов __new__
завершится неудачно, как и любой другой вызов функции, если вы не дадите ему правильные аргументы, потому что type(x).__new__
- это просто функция, как любая другая функция. Вы можете увидеть это с помощью определяемого пользователем класса:
>>> class Foo(object):
... pass
>>> x = Foo(); print type(x).__new__(x.__class__)
<__main__.Foo object at 0x00EB0370>
>>> class Foo(object):
... def __init__(self, someArg):
... pass
>>> class Foo(object):
... def __new__(cls, someArg):
... return super(Foo, cls).__new__(cls)
>>> x = Foo(2); print type(x).__new__(x.__class__)
Traceback (most recent call last):
File "<pyshell#32>", line 1, in <module>
x = Foo(2); print type(x).__new__(x.__class__)
TypeError: __new__() takes exactly 2 arguments (1 given)
Это удалось в первом случае, потому что мой класс не требовал аргументов; он не прошел во втором классе, потому что второй класс требует аргументов.
__new__
не подлежит какой-либо секретной причине; он просто терпит неудачу, потому что тип, который вы пытаетесь создать, требует аргументов, чтобы построить экземпляр. (Случай None
является единственным, который здесь различен, потому что он не работает по особой причине, потому что None
является специальным объектом в Python.)