Чего вы хотите достичь? Можно получить доступ к классу, чтобы настроить его определение с помощью метакласса, но это не рекомендуется.
Ваш образец кода может быть написан просто как:
class A(object):
pass
some_func(A)
я не рекомендую пытаться определить или использовать функцию, которая вычисляет, пусто ли какое-либо значение в целом мире. Что это действительно означает быть "пустым"? Если я имею let human = { name: 'bob', stomach: 'empty' }
, isEmpty(human)
должен возвратиться true
? Если я имею let reg = new RegExp('');
, isEmpty(reg)
должен возвратиться true
? Что относительно [1 110] - этот список только содержит пустоту, так сам список, пустой? Я хочу выдвинуть здесь некоторые примечания по "вырожденности" (намеренно неясное слово, постараться не существовать ранее ассоциации) в JavaScript - и я хочу утверждать, что с "вырожденностью" в значениях JavaScript никогда нельзя иметь дело в общем.
Для решения, как определить "вырожденность" значений, мы должны разместить встроенный, свойственный смысл JavaScript того, являются ли значения "truthy" или "falsy". Естественно, null
и undefined
оба "falsy". Менее естественно номер 0
(и никакое другое число кроме [1 114]) также "falsy". Наименее естественно: ''
falsy, но []
и {}
(и new Set()
, и new Map()
) truthy - хотя они все кажутся одинаково вырожденными!
существует также некоторое обсуждение относительно [1 120] по сравнению с [1 121] - нам действительно нужны оба для выражения вырожденности в наших программах? Я лично стараюсь не когда-либо иметь буквы U, n, d, e, f, я, n, e, d появляюсь в своем коде в том порядке. Я всегда использую null
для выражения "вырожденности". Снова, тем не менее, мы должны разместить свойственный смысл JavaScript того, как null
и undefined
отличайтесь:
undefined
undefined
:
let f = a => a;
console.log(f('hi'));
console.log(f());
undefined
, не null
:
let f = (v='hello') => v;
console.log(f(null));
console.log(f(undefined));
я полагаю, что с вырожденностью никогда нельзя иметь дело универсальным способом. У нас должна вместо этого всегда быть суровость для получения большей информации о наших данных прежде, чем определить, вырождено ли это - я главным образом делаю это путем проверки, с какими данными я имею дело:
let isType = (value, Cls) => {
try {
return Object.getPrototypeOf(value).constructor === Cls;
} catch(err) {
return false;
}
};
Примечание, что эта функция игнорирует полиморфизм - это ожидает value
быть прямым экземпляром [1 130] и не экземпляром подкласса [1 131]. Я избегаю instanceof
по двум главным причинам:
([] instanceof Object) === true
("Массив Объект") ('' instanceof String) === false
("Строка не Строка") Примечание, которое Object.getPrototypeOf
используется для предотвращения случая как [1 136] Эти isType
, функция все еще возвращается правильно для [1 138] (ложь), и isType(v, Object)
(верный).
В целом, я рекомендую использовать этот isType
функция наряду с этими подсказками:
v
переменная теперь имеет неизвестный тип. Как можно раньше мы должны ограничить наши возможности. Лучший способ сделать это может быть путем требования конкретного типа: например, if (!isType(v, Array)) throw new Error('Expected Array');
- это - действительно быстрый и выразительный способ удалить универсальную природу [1 144] и гарантировать, что это всегда Array
. Иногда, тем не менее, мы должны позволить v
иметь несколько типов. В тех случаях мы должны создать блоки кода, где v
больше не универсально, как можно раньше:
if (isType(v, String)) {
/* v isn't generic in this block - It's a String! */
} else if (isType(v, Number)) {
/* v isn't generic in this block - It's a Number! */
} else if (isType(v, Array)) {
/* v isn't generic in this block - it's an Array! */
} else {
throw new Error('Expected String, Number, or Array');
}
if (v === null) throw new Error('Null value rejected');
- здорово для обеспечения, чтобы null
значения не удавались, но если значение делает , удаются, мы все еще знаем едва что-либо об этом. Значение v
, который передает эту пустую проверку, все еще ОЧЕНЬ универсально - это что-либо кроме [1 151] ! Черные списки едва рассеивают универсальный. , Если значение не null
, никогда не рассматривайте "вырожденное значение". Вместо этого рассмотрите "X, который вырожден". По существу, никогда не рассматривайте выполнение ничего как [1 153] - неважно, как тот isEmpty
функция реализована (я не хочу знать...), это не значимо! И это слишком универсально! Вырожденность должна только быть вычислена со знанием [1 155] тип. Проверки вырожденности должны быть похожими на это:
if (isType(val, String) && val.length === 0) ...
if (isType(val, Object) && Object.entries(val).length === 0) ...
if (isType(val, Number) && val <= 0) ...
"Массив, без объектов": if (isType(val, Array) && val.length === 0) ...
единственное исключение - когда null
используется для выражения определенной функциональности. В этом случае это значимо для высказывания: "Вырожденное значение": if (val === null) ...
Если Вы не хотите становиться верными, если значение является каким-либо из следующих, согласно ответ jAndy :
Одно возможное решение, которое могло бы постараться не получать значения truthy, следующее:
function isUsable(valueToCheck) {
if (valueToCheck === 0 || // Avoid returning false if the value is 0.
valueToCheck === '' || // Avoid returning false if the value is an empty string.
valueToCheck === false || // Avoid returning false if the value is false.
valueToCheck) // Returns true if it isn't null, undefined, or NaN.
{
return true;
} else {
return false;
}
}
Это использовалось бы следующим образом:
if (isUsable(x)) {
// It is usable!
}
// Make sure to avoid placing the logical NOT operator before the parameter (isUsable(!x)) and instead, use it before the function, to check the returned value.
if (!isUsable(x)) {
// It is NOT usable!
}
<час> В дополнение к тем сценариям, можно хотеть возвратить false, если объект или массив пуст:
Вы пошли бы об этом этим путем:
function isEmptyObject(valueToCheck) {
if(typeof valueToCheck === 'object' && !Object.keys(valueToCheck).length){
// Object is empty!
return true;
} else {
// Object is not empty!
return false;
}
}
function isEmptyArray(valueToCheck) {
if(Array.isArray(valueToCheck) && !valueToCheck.length) {
// Array is empty!
return true;
} else {
// Array is not empty!
return false;
}
}
, Если Вы хотите проверить на все пробельные строки (" "), можно сделать следующее:
function isAllWhitespace(){
if (valueToCheck.match(/^ *$/) !== null) {
// Is all whitespaces!
return true;
} else {
// Is not all whitespaces!
return false;
}
}
<час> Примечание: hasOwnProperty
возвращает true для пустых строк, 0, лжи, NaN, пустого указателя, и неопределенный, если переменная была объявлена как какой-либо из них, таким образом, не могло бы быть лучше использовать. Функция может быть изменена для использования его, чтобы показать, что это было объявлено, но не применимо.