Есть несколько решений для вашей проблемы.
Способ с 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);
Что ж, вы могли бы сделать ...
first,second = foo(True) or (None,None)
first,second = foo(False) or (None,None)
но насколько я знаю, нет более простого способа развернуть None, чтобы заполнить весь кортеж.
Я не вижу, что не так с возвращением (Нет, Нет). Это намного чище, чем предлагаемые здесь решения, которые включают в себя гораздо больше изменений в вашем коде.
Также не имеет смысла, что вы хотите, чтобы None автоматически разбивался на 2 переменные.
Я думаю, что есть проблема абстракции .
Функция должна поддерживать некоторый уровень абстракции, который помогает уменьшить сложность кода.
В этом случае либо функция не поддерживает правильную абстракцию, либо вызывающая сторона не соблюдает ее.
Функция могла быть чем-то вроде get_point2d()
; в этом случае уровень абстракции находится на кортеже, и поэтому возвращение None было бы хорошим способом сообщить о каком-то конкретном случае (например, о несуществующей сущности). Ошибка в этом случае будет заключаться в ожидании двух элементов, тогда как на самом деле единственное, что вы знаете, это то, что функция возвращает один объект (с информацией, связанной с 2-й точкой).
Но это также могло быть что-то вроде get_two_values_from_db()
; в этом случае абстракция будет прервана путем возврата None, потому что функция (как следует из названия) должна возвращать два значения, а не одно !
В любом случае, основная цель использования Функция - снижение сложности - по крайней мере частично потеряна.
Обратите внимание, что этот вопрос не будет ясно отображаться с оригинальным названием; именно поэтому всегда важно давать хорошие имена для функций и методов.
Я не думаю, что есть хитрость. Вы можете упростить свой код вызова до:
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 в качестве значений по умолчанию.
Вы должны быть осторожны со стилем решения 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))
Хорошо, я бы просто вернулся (Нет, Нет), но пока мы находимся в глуши (хех), вот способ использования подкласса кортежа. В другом случае вы не возвращаете 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
def foo(flag):
return ((1,2) if flag else (None, None))
Я нашел решение этой проблемы:
Вернуть 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
Как насчет этого:
$ 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
. Я очень удивлен, что об этом никто не подумал. (Или, если есть, я хотел бы знать, почему они не использовали его.)