Dynamically Get Object's Attribute

Accessing an object property with a dynamically-computed name

There are two ways to access properties of an object:

  • Dot notation: something.bar
  • Bracket notation: something['bar']

The value between the brackets can be any expression. Therefore, if the property name is stored in a variable, you have to use bracket notation:

var something = {
bar: 'foo'
};
var foo = 'bar';

// both x = something[foo] and something[foo] = x work as expected
console.log(something[foo]);
console.log(something.bar)

How to dynamically access object attributes in python without boxing?

The __name__ attribute of built-in functions is implemented (on the CPython reference interpreter) as a property (technically, a get-set descriptor), not stored as an attribute in the form of a Python object.

Properties act like attributes, but call a function when the value is requested, and in this case, the function converts the C-style string name of the function to a Python str on demand. So each time you look up dir.__name__, you get freshly constructed str representing the data; as noted in the comments, this means there is no way to have an is check pass; even dir.__name__ is dir.__name__ returns False, because each lookup of __name__ returned a new str.

The language gives no guarantees of how __name__ is implemented, so you shouldn't be assuming it returns the same object each time. There are very few language guaranteed singletons (None, True, False, Ellipsis and NotImplemented are the biggies, and all classes have unique identities); assuming is will work with anything not in that set when it's not an object you controlled the creation of is a bad idea. If you want to check if the values are the same, test with ==, not is.

Update to address traversing an arbitrary graph of python objects without getting hung up by descriptors and other stuff (like __getattr__) that dynamically generate objects (and therefore shouldn't be invoked to describe the static graph):

The inspect.getattr_static function should let you "traverse an arbitrary graph of python objects reachable from a starting one while assuming as little possible about the types of objects and the implementation of their attributes" (as your comment requested). When the attribute is actually an attribute, it returns the value, but it doesn't trigger dynamic lookup for descriptors (like @property), __getattr__ or __getattribute__. So inspect.getattr_static(dir, '__name__') will return the getset_descriptor that CPython uses to implement __name__ without actually retrieving the string. On a different object where __name__ is a real attribute (e.g. the inspect module itself), it will return the attribute (inspect.getattr_static(inspect, '__name__') returns 'inspect').

While it's not perfect (some properties may actually be backed by real Python objects, not dynamically generated ones, that you can't otherwise access), it's at least a workable solution; you won't end up creating new objects by accident, and you won't end up in infinite loops of property lookup (e.g. every callable can have __call__ looked up on it forever, wrapping itself over and over as it goes), so you can at least arrive at a solution that mostly reflects the object graph accurately, and doesn't end up recursing to death.

Notably, it will preserve identity semantics properly. If two objects have the same attribute (by identity), the result will match as expected. If two objects share a descriptor (e.g. __name__ for all built-in functions, e.g. bin, dir), then it returns the descriptor itself, which will match on identity. And it does it all without needing to know up front if what you have is an attribute or descriptor.

How to dynamically access an attribute of an object in Python?

You can use getattr to reference any attribute by string

getattr(df[1].dt, granularity_val).values.tolist()

Dynamically access object properties using a variable

Make use of brackets notation for accessing dynamic keys

var my_object = {    object1: {    key: 'value',    key2: 'value2'  },  object2: {    key: 'othervalue',    key2: 'another'  }}
function doSomething(obj_key) { // add a new property to the object my_object[obj_key].new_prop = 'this_new_prop'; // using bracket notation here}
doSomething('object1');
console.dir(my_object);

How to get object attributes to update dynamically in Python

If you want instance attributes that depend on other instance attributes, properties are the way to go.

class Example:
def __init__(self, n):
self.name = n
self.inA = 1
self.inB = 1

@property
def outA(self):
return self.inA and self.inB

You access outA like a regular instance attribute, obj.outA.

>>> my_obj = Example("example")
>>> my_obj.outA
1

Changing the attributes inA and inB affect outA.

>>> my_obj.inA = 0
>>> my_obj.outA
0

how to read object attribute dynamically in java?

You want to use The Reflection API. Specifically, take a look at discovering class members.

You could do something like the following:

public void showFields(Object o) {
Class<?> clazz = o.getClass();

for(Field field : clazz.getDeclaredFields()) {
//you can also use .toGenericString() instead of .getName(). This will
//give you the type information as well.

System.out.println(field.getName());
}
}

I just wanted to add a cautionary note that you normally don't need to do anything like this and for most things you probably shouldn't. Reflection can make the code hard to maintain and read. Of course there are specific cases when you would want to use Reflection, but those relatively rare.

Is it possible to add dynamically named properties to JavaScript object?

Yes.

var data = {    'PropertyA': 1,    'PropertyB': 2,    'PropertyC': 3};
data["PropertyD"] = 4;
// dialog box with 4 in italert(data.PropertyD);alert(data["PropertyD"]);

How to access attributes in object dynamically in Raku

You changed your post to add a question about how to do something like this:

role acc [ Str $member] does Associative[Cool,Str] { ... }

class ports does acc["ports_"] { has @!ports_; ... }

The answer is of course, don't do that.

I mean you can, but you really shouldn't.

I mean you really really shouldn't.

Also you indicate that you want to use [] for indexing.
The thing is that is Positional not Associative.

(I'm ignoring the fact that there is no point to add _ to the end of the attribute name. Usually in Perl or Python adding _ indicated private, but we don't need to do that in Raku.)


The right way to do that is to have the array inside of the role.

role Array::Access [::OF = Cool] does Positional[OF] {
has OF @!array-access handles < AT-POS >;
}

class Ports does Array::Access {
# allows you to access it as self!ports inside of this class
method !ports () is raw { @!array-access }
}

Which shows that adding a role to do that is probably overkill.

class Ports does Positional[Cool] {
has Cool @!ports handles < AT-POS >;
}

If you really, really want to do it they way you asked for, the following works.

role Inner::Array::Access [ Str:D \name, ::OF = Cool ] does Positional[OF] {
# a way to quickly access the attribute
# (hopefully no-one tries to add an attribute of this name to their class)
has $!inner-array handles < AT-POS >;

# set $!inner-array
submethod TWEAK (){
$!inner-array := self.^attributes.first(name).get_value(self);
}
}

class Ports does Inner::Array::Access['@!ports'] {
has @!ports;

# a quick way to add a way to set @!ports for our test
submethod BUILD( :@!ports ){}
}

my Ports $v = ports => [0,10,20,30];

say $v[2]; # 20

Probably what you were thinking is embed the self.^attributes thing into AT‍-‍POS.

role Inner::Array::Access [ Str:D \name, ::OF = Cool ] does Positional[OF] {
method AT-POS ( \index ) is raw {
self.^attributes.first(name).get_value(self).AT-POS(index);
}
}

That would be slow, because it has to do all of those lookups everytime you access a single element.

How to dynamically return Object attributes in python, including attributes of objects that are attributes

I was able to figure this out - I just wrote a quick function that splits the attribute string (for example outputObj.subObj.propertyIWant) then proceeds down the resultant array, calling getattr on each subobject until it reaches the end of the array and returns the actual attribute.

Code:

def obtainAttribute(sample, attributeString: str):
baseObj = sample
attrArray = attributeString.split(".")
for string in attrArray:
if(attrArray.index(string) == (len(attrArray) - 1)):
return getattr(baseObj,string)
else:
baseObj = getattr(baseObj,string)
return "failed"

sample is the object and attributeString is, for example object.subObject.attributeYouWant



Related Topics



Leave a reply



Submit