вернуть что-то кроме объекта при создании объекта - PullRequest
2 голосов
/ 15 марта 2012

Я хочу создать класс, который не будет создавать экземпляры, основываясь на входных параметрах. Для простого примера, если я хочу создать объект, который может существовать, только если один из его входных параметров> 1, тогда

foo = new_object(0.1)

должен возвращать None в foo вместо объекта.

Мне кажется, это элегантный способ создания объектов, так как это означает, что мне не нужен код вне класса, чтобы решить, создавать его или нет

Есть ли способ сделать это, или столь же полезный, это будет плохая практика, и почему?

Ответы [ 3 ]

3 голосов
/ 15 марта 2012

Вам нужно переопределить __new__ - убедитесь, что он принимает те же аргументы, что и __init__:

class Test(object):
    def __init__(self, value):
        self.value = value
    def __new__(cls, value):
        if value > 1:
            return object.__new__(cls)
        return None
    def __repr__(self):
        return "Test value %d" % self.value


t1 = Test(2)
print repr(t1)
t2 = Test(1)
print repr(t2)

Python поддерживает возврат объектов различных типов из __new__, но это довольно редкая практика.

В вашем случае, если вы выбираете между

if value < 1:
    foo = None
else:
    foo = Test(value)

и

foo = Test(value)  # will None if value <= 1

и это то, что вы должны делать много раз, тогда я бы определенно подумал, чтобы класс сделал это.

В тех случаях, когда вы не можете контролировать new_object, вы можете сделать свою собственную фабричную функцию:

def maybe_foo(value):
    if value > 1:
        return new_object(value)
    return None
2 голосов
/ 15 марта 2012

Вы можете переопределить __new__(), чтобы эффективно превратить создание объекта в фабричную операцию, как вы хотите сделать здесь.Иногда мне нравится использовать __new__() абстрактного базового класса в качестве фабрики для конкретных подклассов, если список конкретных подклассов может быть ограничен и известен.Просто убедитесь, что это лучшее решение для вашей проблемы, поскольку, вероятно, это не так ...

1 голос
/ 15 марта 2012

Совершенно очевидно, что это было бы плохой практикой по той простой причине, что никто так не делает.Вызов конструктора должен создать экземпляр объекта, а не выборочно решать, хочет он этого или нет.Вы не должны проверять ошибки при построении объектов.Так что у него довольно высокая «квота wtf», что никогда не является хорошей идеей.

Тем не менее, я не уверен, возможно ли это вообще, поскольку __init__() запускается на экземпляре после того, как он уже былсоздан (и не заканчивается return self).Это, будучи Python, я уверен, что что-то можно спорить.Я считаю, что это плохая идея.

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