Внутри __init__()
(или любого метода класса, если на то пошло), self
- это локальная переменная, привязанная к объекту, для которого был вызван этот метод. Назначение ему повлияет только на привязку этой локальной переменной, оно не изменит фактическую ссылку на объект, существующий вне метода.
К тому времени, когда вы доберетесь до __init__
, объект уже выделен - вы можете отменить это с помощью некоторой "хитрости", но я не уверен, что это будет хорошая идея, даже , если возможно.
нормальный (a) способ справиться с проблемами инициализации - просто выбросить исключение, которое может быть перехвачено, чтобы повторно привязать переменную соответствующим образом (или сделать что-то еще по мере необходимости) :
try:
item = className()
except:
item = None
Вы даже можете предоставить вспомогательную функцию, которая сделает за вас тяжелую работу, так что построение по-прежнему занимает только одну строку, что-то вроде:
class ClassName:
def __init__(self, makeFail):
if makeFail: raise Exception("ouch")
def tryMake(cls, *args):
try:
return cls(*args)
except:
return None
print(tryMake(ClassName, False)) # equiv: print(ClassName(False))
print(tryMake(ClassName, True))
Как видно из на выходе он преобразует неудачную конструкцию в None
:
<__main__.ClassName object at 0x7f7ed1e38c70>
None
Однако существует другая возможность, если вы действительно хотите сделать что-то вроде того, что вы предлагаете, но не хотите перехватывать исключения или повторно связываться с помощью вспомогательной функции.
Есть другая magi c функция __new__
, которая вызывается до __init__
и которая является способной возвращать другой тип. Только если он вернет запрошенный тип, будет Python, а затем __init__
.
Следовательно, вы можете определить вызов __new__
для проверки цены и отказаться от создания экземпляра типа, если он недействителен, согласно приведенный ниже пример кода:
class Item:
def __new__(cls, item, price):
if price < 0:
return None
return super(Item, cls).__new__(cls)
def __init__(self, item, price):
self.item = item
self.price = price
def __str__(self):
return f"({self.item}, {self.price})"
print(Item("Coffee", 4.50))
print(Item("Tea", -1))
print(Item("Biscuit", 2.75))
Кажется, что результат будет таким, как вы хотите:
(Coffee, 4.5)
None
(Biscuit, 2.75)
Теперь это, вероятно, не то, что I сделал бы , вместо этого предпочитая генерировать исключение в __init__()
и позволить вызывающей стороне позаботиться об этом любым способом, который они выберут (включая использование вспомогательной функции, если это необходимо).
(a) Определено как:
normal (n) - таким образом, чтобы не вызывать Python разработчиков, чтобы поставить под сомнение вашу вменяемость: -)