На самом деле, я думаю, что это лучший способ.
from django.core.validators import URLValidator
from django.core.exceptions import ValidationError
val = URLValidator(verify_exists=False)
try:
val('http://www.google.com')
except ValidationError, e:
print e
Если вы установите verify_exists
на True
, он действительно проверит, существует ли URL-адрес, иначе он просто проверит,
edit: ah yeah, этот вопрос является дубликатом этого: Как проверить, существует ли URL с валидаторами Django?
К сожалению, идеального способа не существует, если только вы не используете _proto_
рекурсивно и не обращаетесь ко всем неперечисляемым свойствам, но это работает только в Firefox.
Итак, лучшее, что я можно угадать сценарии использования.
Работает, когда у вас есть простые объекты в стиле JSON без методов и узлов DOM внутри:
JSON.stringify(obj1) === JSON.stringify(obj2)
ПОРЯДОК свойств ВАЖЕН, поэтому этот метод вернет false для следующих объектов:
x = {a: 1, b: 2};
y = {b: 2, a: 1};
Сравнивает объекты, не копаясь в прототипах, затем рекурсивно сравнивает проекции свойств, а также сравнивает конструкторы.
Это почти правильный алгоритм:
function deepCompare () {
var i, l, leftChain, rightChain;
function compare2Objects (x, y) {
var p;
// remember that NaN === NaN returns false
// and isNaN(undefined) returns true
if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
return true;
}
// Compare primitives and functions.
// Check if both arguments link to the same object.
// Especially useful on the step where we compare prototypes
if (x === y) {
return true;
}
// Works in case when functions are created in constructor.
// Comparing dates is a common scenario. Another built-ins?
// We can even handle functions passed across iframes
if ((typeof x === 'function' && typeof y === 'function') ||
(x instanceof Date && y instanceof Date) ||
(x instanceof RegExp && y instanceof RegExp) ||
(x instanceof String && y instanceof String) ||
(x instanceof Number && y instanceof Number)) {
return x.toString() === y.toString();
}
// At last checking prototypes as good as we can
if (!(x instanceof Object && y instanceof Object)) {
return false;
}
if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
return false;
}
if (x.constructor !== y.constructor) {
return false;
}
if (x.prototype !== y.prototype) {
return false;
}
// Check for infinitive linking loops
if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
return false;
}
// Quick checking of one object being a subset of another.
// todo: cache the structure of arguments[0] for performance
for (p in y) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
}
else if (typeof y[p] !== typeof x[p]) {
return false;
}
}
for (p in x) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
}
else if (typeof y[p] !== typeof x[p]) {
return false;
}
switch (typeof (x[p])) {
case 'object':
case 'function':
leftChain.push(x);
rightChain.push(y);
if (!compare2Objects (x[p], y[p])) {
return false;
}
leftChain.pop();
rightChain.pop();
break;
default:
if (x[p] !== y[p]) {
return false;
}
break;
}
}
return true;
}
if (arguments.length < 1) {
return true; //Die silently? Don't know how to handle such case, please help...
// throw "Need two or more arguments to compare";
}
for (i = 1, l = arguments.length; i < l; i++) {
leftChain = []; //Todo: this can be cached
rightChain = [];
if (!compare2Objects(arguments[0], arguments[i])) {
return false;
}
}
return true;
}
] Известные проблемы (ну, у них очень низкий приоритет, возможно, вы их никогда не заметите):
Тесты: проходит тесты из Как определить равенство для двух объектов JavaScript? ].
Я немного изменил код выше. для меня 0! == false и null! == undefined . Если вам не нужна такая строгая проверка, удалите один « = » знак « this [p]! == x [p] » внутри кода.
Object.prototype.equals = function(x){
for (var p in this) {
if(typeof(this[p]) !== typeof(x[p])) return false;
if((this[p]===null) !== (x[p]===null)) return false;
switch (typeof(this[p])) {
case 'undefined':
if (typeof(x[p]) != 'undefined') return false;
break;
case 'object':
if(this[p]!==null && x[p]!==null && (this[p].constructor.toString() !== x[p].constructor.toString() || !this[p].equals(x[p]))) return false;
break;
case 'function':
if (p != 'equals' && this[p].toString() != x[p].toString()) return false;
break;
default:
if (this[p] !== x[p]) return false;
}
}
return true;
}
Затем я проверил это со следующими объектами:
var a = {a: 'text', b:[0,1]};
var b = {a: 'text', b:[0,1]};
var c = {a: 'text', b: 0};
var d = {a: 'text', b: false};
var e = {a: 'text', b:[1,0]};
var f = {a: 'text', b:[1,0], f: function(){ this.f = this.b; }};
var g = {a: 'text', b:[1,0], f: function(){ this.f = this.b; }};
var h = {a: 'text', b:[1,0], f: function(){ this.a = this.b; }};
var i = {
a: 'text',
c: {
b: [1, 0],
f: function(){
this.a = this.b;
}
}
};
var j = {
a: 'text',
c: {
b: [1, 0],
f: function(){
this.a = this.b;
}
}
};
var k = {a: 'text', b: null};
var l = {a: 'text', b: undefined};
a == b ожидаемое истина; вернул true
a == c ожидал false; вернул ложь
c == d ожидал ложь; вернул ложь
a == e ожидал ложь; вернул false
f == g ожидал true; вернул true
h == g ожидал false; вернул false
i == j ожидал true; вернул true
d == k ожидал false; вернул ложь
k == я ожидал ложь; вернул false
Конечно, это не единственный способ - вы можете создать прототип метода (здесь против Object, но я бы точно не предлагал использовать Object для живого кода) для репликации методов сравнения стилей C # / Java.
Отредактируйте, так как кажется ожидаемым общий пример:
Object.prototype.equals = function(x)
{
for(p in this)
{
switch(typeof(this[p]))
{
case 'object':
if (!this[p].equals(x[p])) { return false }; break;
case 'function':
if (typeof(x[p])=='undefined' || (p != 'equals' && this[p].toString() != x[p].toString())) { return false; }; break;
default:
if (this[p] != x[p]) { return false; }
}
}
for(p in x)
{
if(typeof(this[p])=='undefined') {return false;}
}
return true;
}
Обратите внимание, что методы тестирования с toString () абсолютно не достаточно хороши , но метод, который был бы приемлемым, очень сложен из-за проблемы с пробелами, имеющими значение или нет, не говоря уже о методах-синонимах и методах, дающих одинаковый результат при разных реализациях. И проблемы создания прототипов против Object в целом.
, если вы хотите явно проверить методы, вы можете использовать методы method.toSource () или method.toString ().
Если вы работаете без библиотеки JSON, возможно, это вам поможет:
Object.prototype.equals = function(b) {
var a = this;
for(i in a) {
if(typeof b[i] == 'undefined') {
return false;
}
if(typeof b[i] == 'object') {
if(!b[i].equals(a[i])) {
return false;
}
}
if(b[i] != a[i]) {
return false;
}
}
for(i in b) {
if(typeof a[i] == 'undefined') {
return false;
}
if(typeof a[i] == 'object') {
if(!a[i].equals(b[i])) {
return false;
}
}
if(a[i] != b[i]) {
return false;
}
}
return true;
}
var a = {foo:'bar', bar: {blub:'bla'}};
var b = {foo:'bar', bar: {blub:'blob'}};
alert(a.equals(b)); // alert's a false