Отсюда :
/**
*
* Base64 encode / decode
* http://www.webtoolkit.info/
*
**/
var Base64 = {
// private property
_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
// public method for encoding
encode : function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = Base64._utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = Base64._utf8_decode(output);
return output;
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
}
else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
Кроме того, поиск по «кодировке javascript base64» включает в себя множество других опций, первый.
Краткий ответ: class dict_values
не имеет реализованного метода __eq__
, но class dict_keys
:
>>> d.values().__eq__(d.values())
NotImplemented
>>> d.keys().__eq__(d.keys())
True
Поэтому сравнение d.values()
==
оценивается как False
.
Более длинный ответ , почему он не был реализован, является другим, и его можно увидеть, немного углубившись в документацию объектов dict-view . Эта часть кажется особенно актуальной (выделено мной):
Представления ключей похожи на наборы, поскольку их записи уникальны и доступны для хэширования . Если все значения могут быть хэшируемыми, поэтому пары (ключ, значение) уникальны и хэшируемы, то представление элементов также задается как набор. (Представления значений не рассматриваются как подобные множеству, поскольку записи, как правило, не являются уникальными.) Для множественных представлений доступны все операции, определенные для абстрактного базового класса
blockquote>collections.abc.Set
(например,==
,<
или^
) . Поскольку ключи должны быть уникальными, имеет смысл, что они подобны множеству и поддерживаются операциями класса из
collections.Set
. Значения не являются подобными множеству из-за неединственности.Однако в Python 2.7
d.keys()
иd.values()
оба возвращаютlist
согласно документации , поэтому это ограничение не применяется. Поскольку оба объекта относятся к одному и тому же типу, имеет смысл использовать одну и ту же операцию для обоих. Если вы использовалиviewkeys
иviewvalues
, как упомянуто в документации по объектам dict-view в Python2.7 , то вы можете ожидать аналогичного поведения:# Python 2.7 from collections import Set # in Python 3.x this would be from collections.abc import Set d = {"one": 1} print isinstance(d.viewkeys(), Set) # True print isinstance(d.viewvalues(), Set) # False print d.viewkeys() == d.viewkeys() # True print d.viewvalues() == d.viewvalues() # False