2014-10-19 4 views
0

Что является примером использования __new__ в Python таким образом, что в теле __new__ вы сделать не вернуть результат вызова какой-либо другой (основание, мета- или иначе) версию класса по __new__, но вы сделать возвращающих выделенный экземпляр предполагаемого класса, так что будет вызван __init__?Python __new__ без вызова другой версии класса __new__?

Я предполагаю, что это (и должно быть) очень редко, но мне любопытно, есть ли пример этого прецедента. Я попытался найти источник Python для реализации tuple__new__, а также для реализации type, но это не похоже на то, что это быстро и легко найти в Интернете.

+2

Что вы подразумеваете под «выделенным экземпляром»? Есть такие вещи, как [Singleton] (http://stackoverflow.com/a/1810367/1427416), которые используют '__new__' для возврата существующего экземпляра того же класса, но' __new__' по-прежнему используется для построения исходного экземпляра , и повторное вызов '__init__', возможно, даже не желательно там (хотя это происходит в этом примере). Невозможно создать реальный новый экземпляр пользовательского класса без использования встроенного 'object .__ new__' в какой-то момент. 'tuple' и' type' реализованы в C, поэтому они не используют один и тот же API с '__new__'. – BrenBarn

+0

Под «выделенным экземпляром» я имею в виду только то, что возвращает '__new__'. Как вы делаете новые экземпляры вещей, не опускаясь на что-то еще '__new__'? Или это ошибочный вопрос? – ely

+0

Вы не можете. Вы должны либо вызвать что-то еще '__new__', либо просто создать объект, вызвав некоторый другой класс/тип, который под капотом вызовет этот класс' __new__'. – BrenBarn

ответ

1

Вы не можете, это не то, что вы можете сделать на стороне Python. Метод no-op __new__ вызовет object.__new__(cls), который возвращает пустой экземпляр класса cls.

>>> class A: 
...  def __new__(cls): 
...   return object.__new__(cls) 
... 
>>> A() 
<__main__.A object at 0x7f9e951577d0> 
+0

Просто для подтверждения такие вещи, как 'tuple .__ new__',' object .__ new__' и 'type .__ new__', имеют свои реализации на уровне C и определяют единственный набор поведений (в корне его всех) для' __new__'. Для классов на некотором уровне вниз по цепочке вы полагаетесь на какой-то встроенный тип '__new__' (или' object''s), а для метаклассов - то же, что и для 'type'. Есть ли какая-либо неизменяемость в '__new__', кроме неизменяемости последовательности-типа для' tuple'? – ely

+0

@EMS: Что значит «вид неизменности»? – BrenBarn

+0

Подкласс «tuple» - это способ получить некоторые пользовательские вещи и неизменность, но не другие атрибуты класса. Использование дескрипторов - один из способов сделать чтение только для чтения, но не законным. Мне хотелось бы что-то такое, что 'object .__ setattr__' не будет работать, чтобы настроить какие-либо attrs, но которые, возможно, имеют произвольные атрибуты или вещи, определенные в' __new__'. – ely