Возврат Ни одного или кортежа и распаковки

Есть несколько решений для вашей проблемы.

Способ с MySQLi будет таким:

<?php
$connection = mysqli_connect('localhost', 'username', 'password', 'database');

Выполнять запросы базы данных также просто и почти идентично старому путь:

<?php
// Old way
mysql_query('CREATE TEMPORARY TABLE `table`', $connection);
// New way
mysqli_query($connection, 'CREATE TEMPORARY TABLE `table`');

Отключить все устаревшие предупреждения, включая их из mysql _ *:

<?php
error_reporting(E_ALL ^ E_DEPRECATED);
25
задан Stefano Borini 13 August 2009 в 22:03
поделиться

9 ответов

Что ж, вы могли бы сделать ...

first,second = foo(True) or (None,None)
first,second = foo(False) or (None,None)

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

27
ответ дан 28 November 2019 в 17:56
поделиться

Я не вижу, что не так с возвращением (Нет, Нет). Это намного чище, чем предлагаемые здесь решения, которые включают в себя гораздо больше изменений в вашем коде.

Также не имеет смысла, что вы хотите, чтобы None автоматически разбивался на 2 переменные.

21
ответ дан Unknown 28 November 2019 в 17:56
поделиться

Я думаю, что есть проблема абстракции .

Функция должна поддерживать некоторый уровень абстракции, который помогает уменьшить сложность кода.
В этом случае либо функция не поддерживает правильную абстракцию, либо вызывающая сторона не соблюдает ее.

Функция могла быть чем-то вроде get_point2d(); в этом случае уровень абстракции находится на кортеже, и поэтому возвращение None было бы хорошим способом сообщить о каком-то конкретном случае (например, о несуществующей сущности). Ошибка в этом случае будет заключаться в ожидании двух элементов, тогда как на самом деле единственное, что вы знаете, это то, что функция возвращает один объект (с информацией, связанной с 2-й точкой).

Но это также могло быть что-то вроде get_two_values_from_db(); в этом случае абстракция будет прервана путем возврата None, потому что функция (как следует из названия) должна возвращать два значения, а не одно !

В любом случае, основная цель использования Функция - снижение сложности - по крайней мере частично потеряна.

Обратите внимание, что этот вопрос не будет ясно отображаться с оригинальным названием; именно поэтому всегда важно давать хорошие имена для функций и методов.

17
ответ дан rob 28 November 2019 в 17:56
поделиться

Я не думаю, что есть хитрость. Вы можете упростить свой код вызова до:

values = foo(False)
if values:
    first, second = values

или даже:

values = foo(False)
first, second = values or (first_default, second_default)

где first_default и second_default - это значения, которые вы задали бы first и second в качестве значений по умолчанию.

7
ответ дан Ned Batchelder 28 November 2019 в 17:56
поделиться

Вы должны быть осторожны со стилем решения x or y. Они работают, но они немного шире, чем ваша оригинальная спецификация. По сути, что, если foo(True) возвращает пустой кортеж ()? До тех пор, пока вы знаете, что все в порядке, считая (None, None), вы хорошо справляетесь с предоставленными решениями.

Если бы это был распространенный сценарий, я бы, вероятно, написал бы служебную функцию, например:

# needs a better name! :)
def to_tup(t):
    return t if t is not None else (None, None)

first, second = to_tup(foo(True))
first, second = to_tup(foo(False))
2
ответ дан ars 28 November 2019 в 17:56
поделиться

Хорошо, я бы просто вернулся (Нет, Нет), но пока мы находимся в глуши (хех), вот способ использования подкласса кортежа. В другом случае вы не возвращаете None, а вместо этого возвращаете пустой контейнер, который, кажется, соответствует духу вещей. «Итератор» контейнера распаковывает значения None, когда они пустые. В любом случае, демонстрирует протокол итератора ...

Протестировано с использованием v2.5.2:

class Tuple(tuple):
    def __iter__(self):
        if self:
            # If Tuple has contents, return normal tuple iterator...
            return super(Tuple, self).__iter__()
        else:
            # Else return a bogus iterator that returns None twice...
            class Nonerizer(object):
                def __init__(self):
                    self.x=0
                def __iter__(self):
                    return self
                def next(self):
                    if self.x < 2:
                        self.x += 1
                        return None
                    else:
                        raise StopIteration
            return Nonerizer()


def foo(flag):
    if flag:
        return Tuple((1,2))
    else:
        return Tuple()  # It's not None, but it's an empty container.

first, second = foo(True)
print first, second
first, second = foo(False)
print first, second

Выход желаемый:

1 2
None None
1
ответ дан Anon 28 November 2019 в 17:56
поделиться
def foo(flag):
    return ((1,2) if flag else (None, None))
1
ответ дан hughdbrown 28 November 2019 в 17:56
поделиться

Я нашел решение этой проблемы:

Вернуть None или вернуть объект.

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

Вот так:

from collections import namedtuple
def foo(flag):
if flag:
   return None
else:
    MyResult = namedtuple('MyResult',['a','b','c']
    return MyResult._make([1,2,3])

А затем:

result = foo(True) # result = True
result = foo(False) # result = MyResult(a=1, b=2, c=3)

И у вас есть доступ к результаты, как это:

print result.a # 1
print result.b # 2
print result.c # 3
0
ответ дан Diego 28 November 2019 в 17:56
поделиться

Как насчет этого:

$ cat foo.py 
def foo(flag):
    if flag:
        return (1,2)
    else:
        return (None,)*2

first, second = foo(True)
first, second = foo(False)

Изменить: Для ясности, единственное изменение - заменить return None на return (None,) * 2 . Я очень удивлен, что об этом никто не подумал. (Или, если есть, я хотел бы знать, почему они не использовали его.)

3
ответ дан 28 November 2019 в 17:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: