Check If Class Has a Value for a Key

Check if class has a value for a key

This is annoying problem. In the following code snippet I use reflection to check whether a call to valueForObject is safe. It might have a huge performance penalty ...

The solution was inspired by this blog post

extension NSObject {
func safeValueForKey(key: String) -> AnyObject? {
let copy = reflect (self)

for index in 0 ..< copy.count {
let (fieldName, fieldMirror) = copy[index]
if (fieldName == key ){
return valueForKey(fieldName)
}

}
return nil
}
}

class A:NSObject {
var name: String = "Awesome"
}

var a = A()
a.safeValueForKey("name") // "Awesome"
a.safeValueForKey("b") // nil

check if a class instance (which serves as a dict key in this case), has all the same attributes as another instance of the same class

I think it's generally best to write out and comapre each attrbute but with 20 attributes you may want a more flexible and simple approach. So for the equality check you could have

def __eq__(self, other):
return isinstance(other, type(self)) and all(v == getattr(other, k)
for k, v in vars(self).items())

As for hashing it depends on which approach you want to take.

def __hash__(self):
result = 1
for k, v in sorted(vars(self).items()):
result = 31 * result + hash(v) # chosen prime is 31
return result

Or you can create a tuple of each value and hash that.

def __hash__(self):
return hash(tuple(v for k, v in sorted(vars(self).items())))

Update:

If some of your attributes are unhashable then you can ignore them like so.

def __hash__(self):
return hash(tuple(v for k, v in sorted(vars(self).items())
if getattr(v, '__hash__') is not None))

Otherwise take the first approach and handle how they get hashed in the loop.

Finding if a class is key-value-compliant for a given key

you can ask if it responds to the selector, or ask for the value for key

//will check for the getter
[anObj respondsToSelector:@selector(someKey)]

//will check in a way that doesn't throw an exception for a value
[andObj valueForKey:@"someKey"]

//keypath of a nested value
[anObj valueForKeypath:@"child.property"]

but if you are getting a message that something isn't KVC compliant that usually means you have set something up incorrectly, a binding with the wrong key or class for instance.

How do you tell if a key exists for an object using Key-Value Coding?

If you are creating the object that is being checked, you could override valueForUndefinedKey: and setValue:forUndefinedKey to do something more useful than raising an exception.

If, on the other hand, you are trying to introspect objects you don't know about at runtime, you will have to use the runtime methods to do that. You can either use the objective-c runtime itself and call either class_copyPropertyList or protocol_copyPropertyList and deal with those, or use Foundation and call respondsToSelector on the object for the KVC getter/setters for a given property, e.g., for a property foo you would call something like [someObject respondsToSelector:NSSelectorFromString(@"foo")];.

Check if class property value exists in list of objects

Use any:

class ButtonPress():
def __init__(self, time, button):
self.time = time
self.button = button

buttonlist = []
buttonlist.append(ButtonPress("25", "a"))
buttonlist.append(ButtonPress("5", "b"))

if any(button.time == "25" for button in buttonlist):
print("yaaay")
else:
print("feck")

Output

yaaay

An alternative using in is the following:

if "25" in (button.time for button in buttonlist):

How do I check if an object has an attribute?

Try hasattr():

if hasattr(a, 'property'):
a.property

See zweiterlinde's answer below, who offers good advice about asking forgiveness! A very pythonic approach!

The general practice in python is that, if the property is likely to be there most of the time, simply call it and either let the exception propagate, or trap it with a try/except block. This will likely be faster than hasattr. If the property is likely to not be there most of the time, or you're not sure, using hasattr will probably be faster than repeatedly falling into an exception block.

How do I check if an object has a key in JavaScript?

Try the JavaScript in operator.

if ('key' in myObj)

And the inverse.

if (!('key' in myObj))

Be careful! The in operator matches all object keys, including those in the object's prototype chain.

Use myObj.hasOwnProperty('key') to check an object's own keys and will only return true if key is available on myObj directly:

myObj.hasOwnProperty('key')

Unless you have a specific reason to use the in operator, using myObj.hasOwnProperty('key') produces the result most code is looking for.

How do I check if an object has a specific property in JavaScript?

2022 UPDATE

Object.hasOwn()

Object.hasOwn() is recommended over Object.hasOwnProperty() because it works for objects created using Object.create(null) and with objects that have overridden the inherited hasOwnProperty() method. While it is possible to workaround these problems by calling Object.prototype.hasOwnProperty() on an external object, Object.hasOwn() is more intuitive.

Example

const object1 = {
prop: 'exists'
};

console.log(Object.hasOwn(object1, 'prop'));
// expected output: true


Original answer

I'm really confused by the answers that have been given - most of them are just outright incorrect. Of course you can have object properties that have undefined, null, or false values. So simply reducing the property check to typeof this[property] or, even worse, x.key will give you completely misleading results.

It depends on what you're looking for. If you want to know if an object physically contains a property (and it is not coming from somewhere up on the prototype chain) then object.hasOwnProperty is the way to go. All modern browsers support it. (It was missing in older versions of Safari - 2.0.1 and older - but those versions of the browser are rarely used any more.)

If what you're looking for is if an object has a property on it that is iterable (when you iterate over the properties of the object, it will appear) then doing: prop in object will give you your desired effect.

Since using hasOwnProperty is probably what you want, and considering that you may want a fallback method, I present to you the following solution:

var obj = {
a: undefined,
b: null,
c: false
};

// a, b, c all found
for ( var prop in obj ) {
document.writeln( "Object1: " + prop );
}

function Class(){
this.a = undefined;
this.b = null;
this.c = false;
}

Class.prototype = {
a: undefined,
b: true,
c: true,
d: true,
e: true
};

var obj2 = new Class();

// a, b, c, d, e found
for ( var prop in obj2 ) {
document.writeln( "Object2: " + prop );
}

function hasOwnProperty(obj, prop) {
var proto = obj.__proto__ || obj.constructor.prototype;
return (prop in obj) &&
(!(prop in proto) || proto[prop] !== obj[prop]);
}

if ( Object.prototype.hasOwnProperty ) {
var hasOwnProperty = function(obj, prop) {
return obj.hasOwnProperty(prop);
}
}

// a, b, c found in modern browsers
// b, c found in Safari 2.0.1 and older
for ( var prop in obj2 ) {
if ( hasOwnProperty(obj2, prop) ) {
document.writeln( "Object2 w/ hasOwn: " + prop );
}
}

The above is a working, cross-browser, solution to hasOwnProperty(), with one caveat: It is unable to distinguish between cases where an identical property is on the prototype and on the instance - it just assumes that it's coming from the prototype. You could shift it to be more lenient or strict, based upon your situation, but at the very least this should be more helpful.

Checking if a variable belongs to a class in python

You could use the __dict__ property which composes a class, for example:

In [1]: class Foo(object):
...: bar = "b"
...: zulu = "z"
...:
In [2]: "bar" in Foo.__dict__
Out[2]: True

Or as you're searching for the values use __dict__.values():

In [3]: "b" in Foo.__dict__.values()
Out[3]: True

As Peter Wood points out, the vars() built-in can also be used to retrieve the __dict__:

In [12]: "b" in vars(Foo).values()
Out[12]: True

The __dict__ property is used as a namespace for classes and so will return all methods, magic methods and private properties on the class as well, so for robustness you might want to modify your search slightly to compensate.

In your case, you might want to use a classmethod, such as:

class States(object):
ALABAMA = "AL"
FLORIDA = "FL"

@classmethod
def is_state(cls, to_find):
print(vars(cls))
states = [val for key, val in vars(cls).items()
if not key.startswith("__")
and isinstance(val, str)]
return to_find in states

States.is_state("AL") # True
States.is_state("FL") # True
States.is_state("is_state") # False
States.is_state("__module__") # False

Update
This clearly answer's the OPs question, but readers may also be interested in the Enum library in Python 3, which would quite possibly be a better container for data such as this.



Related Topics



Leave a reply



Submit