Предположим, что у вас есть следующий код
fruits = ("apples", "bananas", "loganberries")
def eat(food=fruits):
...
Когда я вижу декларацию о еде, наименее удивительной является мысль, что если первый параметр не указан, он будет равен tuple ("apples", "bananas", "loganberries")
Однако, предположим позже в коде, я делаю что-то вроде
def some_random_function():
global fruits
fruits = ("blueberries", "mangos")
, тогда, если параметры по умолчанию были связаны с выполнением функции, а не с объявлением функции, тогда я бы удивляйтесь (очень плохо), чтобы обнаружить, что фрукты были изменены. Это было бы более удивительно ИМО, чем обнаружение того, что ваша функция foo
, указанная выше, мутировала список.
Реальная проблема заключается в изменяемых переменных, и все языки имеют определенную проблему. Возникает вопрос: предположим, что в Java у меня есть следующий код:
StringBuffer s = new StringBuffer("Hello World!");
Map<StringBuffer,Integer> counts = new HashMap<StringBuffer,Integer>();
counts.put(s, 5);
s.append("!!!!");
System.out.println( counts.get(s) ); // does this work?
Теперь, использует ли моя карта значение ключа StringBuffer
, когда оно было помещено на карту, или оно хранит ключ по ссылке? В любом случае, кто-то удивлен; либо человек, который попытался получить объект из Map
, используя значение, идентичное тому, с которым он положил его, или человек, который, похоже, не может получить свой объект, даже если ключ, который они используют, буквально тот же объект, который использовался для размещения его на карте (на самом деле Python не позволяет использовать его изменяемые встроенные типы данных в качестве словарных клавиш).
Ваш пример хороший случая, когда новички Python будут удивлены и укушены. Но я бы сказал, что если бы мы «исправили» это, тогда это создало бы другую ситуацию, в которой они были бы укушены, и это было бы еще менее интуитивным. Более того, это всегда имеет место при работе с изменяемыми переменными; вы всегда сталкиваетесь с ситуациями, когда кто-то может интуитивно ожидать одно или наоборот поведения в зависимости от того, какой код они пишут.
Мне лично нравится текущий подход Python: аргументы функции по умолчанию оцениваются, когда функция определена, и что объект всегда является значением по умолчанию. Я предполагаю, что они могут использовать специальный случай с пустым списком, но такой специальный корпус вызовет еще большее удивление, не говоря уже о несовместимости в обратном направлении.
useTimezone - это более раннее решение. Команда MySQL переписала код setTimestamp / getTimestamp довольно недавно, но она будет включена, только если вы установили параметр соединения useLegacyDatetimeCode = false, и вы используете последнюю версию соединителя JDBC mysql. Например:
String url =
"jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false
Если вы загрузите исходный код mysql-коннектора и посмотрите на setTimestamp, очень легко увидеть, что происходит:
Если использовать устаревший код времени даты = false, newSetTimestampInternal (...). Затем, если Календарь, переданный в newSetTimestampInternal, равен NULL, ваш объект даты форматируется в часовом поясе базы данных:
this.tsdf = new SimpleDateFormat("''yyyy-MM-dd HH:mm:ss", Locale.US);
this.tsdf.setTimeZone(this.connection.getServerTimezoneTZ());
timestampString = this.tsdf.format(x);
Очень важно, чтобы Calendar был нулевым - поэтому убедитесь, что вы используете:
setTimestamp(int,Timestamp).
... NOT setTimestamp (int, Timestamp, Calendar).
Теперь должно быть очевидно, как это работает. Если вы построите дату: 5 января 2011 г. 3:00 в Америке / Los_Angeles (или любой другой часовой пояс, который вы хотите), используя java.util.Calendar и call setTimestamp (1, myDate), тогда он примет вашу дату, используйте SimpleDateFormat для его форматирования в часовом поясе базы данных. Итак, если ваша БД находится в Америке / New_York, она построит String '2011-01-05 6:00:00', чтобы вставить (поскольку NY опережает LA на 3 часа).
To получить дату, использовать getTimestamp (int) (без календаря).
Примечание: часовой пояс веб-сервера совершенно неактуален! Если вы не установили для useLegacyDatetimecode значение false, временной интервал веб-сервера используется для форматирования - добавление большого количества путаницы.
Примечание:
Возможно, MySQL мой жалуется, что серверный часовой пояс неоднозначен. Например, если ваша база данных настроена на использование EST, в Java может быть несколько возможных часовых поясов EST, поэтому вы можете пояснить это для mysql-коннектора, указав точно, что такое часовой пояс базы данных:
String url =
"jdbc:mysql://localhost/mydb?useLegacyDatetimeCode=false&serverTimezone=America/New_York";
Вам нужно только сделать это, если он жалуется.
6.0.2
– James111 9 June 2016 в 08:05