Предположим, что у вас есть следующий код
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: аргументы функции по умолчанию оцениваются, когда функция определена, и что объект всегда является значением по умолчанию. Я предполагаю, что они могут использовать специальный случай с пустым списком, но такой специальный корпус вызовет еще большее удивление, не говоря уже о несовместимости в обратном направлении.
Вы не можете действительно знать, что находится в буфере обмена пользователя, если вы не использовали какой-либо флеш-бэкэнд при копировании текста.
Обновление: Более правильный ответ здесь
window.clipboardData.getData('Text')
будет работать в некоторых браузерах. Однако многие браузеры, где он работает, подскажут пользователю, хотите ли они, чтобы веб-страница имела доступ к буферу.
В зависимости от того, когда вы читаете это, новый API буфера обмена может быть доступен через navigator.clipboard
. Его можно использовать так:
navigator.clipboard.readText()
.then(text => {
console.log('Pasted content: ', text);
})
.catch(err => {
console.error('Failed to read clipboard contents: ', err);
});
Имейте в виду, что это вызовет у пользователя диалоговое окно с запросом на разрешение, поэтому к сожалению, не смешно.
Далее вы получите выбранный контент, а также обновите буфер обмена.
Свяжите идентификатор элемента с событием копирования, а затем получите выделенный текст. Вы можете заменить или изменить текст. Получите буфер обмена и установите новый текст. Чтобы получить точное форматирование, вам нужно установить тип как «text / hmtl». Вы также можете привязать его к документу вместо элемента.
$(ElementId).bind('copy', function(event) {
var selectedText = window.getSelection().toString();
selectedText = selectedText.replace(/\u200B/g, "");
clipboardData = event.clipboardData || window.clipboardData || event.originalEvent.clipboardData;
clipboardData.setData('text/html', selectedText);
event.preventDefault();
});
Вы можете использовать
window.clipboardData.getData('Text')
, чтобы получить содержимое буфера обмена пользователя в IE. Однако в другом браузере вам может понадобиться использовать flash для получения контента, поскольку для доступа к буферу нет стандартного интерфейса. Возможно, вы можете попробовать этот плагин Zero Clipboard