The reason for not able to access my object item - python-3.x

I am creating a class and setting some properties. And I am referencing dictionary as a class object. But not able to access the second element of the object.
I tried to google the problem but it does not specify the cause of my problem.
data = {
'a': {
'vsdf': 'asfas',
'nfgn': 'aser',
'aser': 'rtydf'
},
'b': ['ndfg', 'ndf', 'safd']
}
My class looks something like this:
def __init__(self, meta):
self.meta = meta
and when i create the object of this class like this:
request = Request(data)
and try to print the request['b'] it shows the error "'Request' object is not subscriptable"
Actual result should be like :
['', '', '']
but it shows:
'Request' object is not subscriptable

With the code you have given, the data dictionary will be stored in the meta instance variable. You'll need to access it by first accessing that variable, i.e. request.meta['b'].
In order to get it to act the way you want, you'll need to loop through the dict passed in to __init__ and set each variable individually. Take a look at this answer for how to do that: Set attributes from dictionary in python

Related

How to make object able to return its properties when triggered by print function

In python if we print some object, it will show their properties when triggered by print function.
For example:
print(int(69)) # 69
Unlike my own defined class like this:
class Foo:
def __init__(self,oke):
self.oke = oke
print(Foo('yeah')) # <__main__.Foo object at 0x000001EB00CDEEB0>
Why It doesn't return oke properties? Instead it show memory address of object?
I expect the output will be:
Foo(oke='yeah')
I know I can define method getter get_oke(), but I want see all properties in an object at once print.
Add a __repr__ method to your class.
From the docs
If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value
class Foo:
def __init__(self,oke):
self.oke = oke
def __repr__(self):
return f'Foo(oke="{self.oke}")'
print(Foo('yeah')) # Foo(oke="yeah")

Extract type hints for object attributes in Python [duplicate]

I want to get the type hints for an object's attributes. I can only get the hints for the class and not an instance of it.
I have tried using foo_instance.__class__ from here but that only shows the class variables.
So in the example how do I get the type hint of bar?
class foo:
var: int = 42
def __init__(self):
self.bar: int = 2
print(get_type_hints(foo)) # returns {'var': <class 'int'>}
I just had the same problem. The python doc isn't that clear since the example is made with what is now officially called dataclass.
Student(NamedTuple):
name: Annotated[str, 'some marker']
get_type_hints(Student) == {'name': str}
get_type_hints(Student, include_extras=False) == {'name': str}
get_type_hints(Student, include_extras=True) == {
'name': Annotated[str, 'some marker']
}
It give the impression that get_type_hints() works on class directly. Turns out get_type_hints() returns hints based on functions, not on class. That way it can be use with both if we know that. A normal class obviously not being instantiated at it's declaration, it does not have any of the variables set within the __init__() method who hasn't yet been called. It couldn't be that way either if we want the possibility to get the type hints from class-wide variables.
So you could either call it on __init__(), that is if variables are passed in arguments though (yes i seen it's not in your example but might help others since i didn't seen this anywhere in hours of search);
class foo:
var: int = 42
def __init__(self, bar: int = 2):
self.bar = int
print(get_type_hints(foo.__init__))
At last for your exact example i believe you have two choices. You could instantiate a temporary object and use del to clean it right after if your logic allows it. Or declare your variables as class ones with or without default values so you can get them with get_type_hints() and assign them later in instantiations.
Maybe this is a hack, and you have to be the creator of your instances, but there are a subset of cases in which using a data class will get you what you want;
Python 3.7+
#dataclass
class Foo:
bar: str = 2
if __name__ == '__main__':
f = Foo()
print(f.bar)
print(get_type_hints(f))
2
{'bar': <class 'str'>}
Hints only exist at the class level — by the time an instance is created the type of its attributes will be that of whatever value has been assigned to them. You can get the type of any instance attribute by using the first form of the built-in type() function — e.g. type(foo_instance.var).
This information isn't evaluated and only exists in the source code.
if you must get this information, you can use the ast module and extract the information from the source code yourself, if you have access to the source code.
You should also ask yourself if you need this information because in most cases reevaluating the source code will be to much effort.

How can I assign a custom object to xarray data values?

I have created a DataArray using xarray successfully:
df_invoice_features = xr.DataArray(data=None,
dims={"y", "x"},
coords={"y": unique_invoices, "x": cols})
I created a custom class and assigned one value of xarray to the instance of this class:
class MyArray:
def __init__(self, s):
self.arr = np.array((s))
def set(self, idx, val):
self.arr[idx] = val
def get(self):
return self.arr
df_invoice_features.loc['basket_value_brand', invoice_id] = MyArray(len_b)
It is created successfully again:
But when I want to update the array of this class instance:
df_invoice_features.loc['basket_value_brand', invoice_id].set(0, 10)
It returns this error:
AttributeError: 'DataArray' object has no attribute 'set'
How can I use an array, dictionary or my custom object inside xarray data values?
So df_invoice_features.loc['basket_value_brand', invoice_id] doesn't actually return MyArray(len_b). Instead, it returns an xarray DataArray; specifically the subset of your full DataArray at the coordinate ['basket_value_brand', invoice_id]. This doesn't just include the value at that location (MyArray(len_b)), but also all the other information stored at that DataArray location; i.e., your coordinates, metadata, etc.
If you want to access the actual value at that location, you'll have to use .values; i.e.,
df_invoice_features.loc['basket_value_brand', invoice_id].values
That should get you the MyArray(len_b) you're looking for. However, I'm not entirely clear what you would like to do with that class. If you're trying to change the value of your DataArray at that location, this bit of the xarray docs in particular may be useful to review.

Collection of objects that are set up only if actually used

I'm writing a class to manage a collection of objects that I'd like to "load" only if actually used (immagine that each object is an heavy document). Also I want to refer to each object both with a numeric key and a string name.
I decided to create a class that inherits from OrderedDict:
from collections import OrderedDict
class MyClass:
def load_me(self, key):
print(f"Object {key} loaded")
class MyClassColl(OrderedDict):
def __getitem__(self, key):
if isinstance(key, int):
key = list(self.keys())[key]
res = super().get(key).load_me(key)
return res
When I initialise the collection and retrieve a single object everything works well and:
my_coll = MyClassColl([('Obj1', MyClass()), ('Obj2', MyClass()), ('Obj3', MyClass())])
my_obj = my_coll['Obj2'] # or my_obj = my_coll[1]
prints:
Object Obj2 loaded
But using a loop, the objects are not properly loaded so:
for key, item in my_coll.items():
obj = item
has not output.
This is because the __getitem__ method is not getting called when you loop through the dictionary like that. It is only called when you use an index operator (as far as I know). So, a super easy fix would be to do your for loop like this:
for key in my_coll:
item = my_coll[key]
Alternatively you could try playing around with the __iter__ method but I think the way you've done it is probably ideal.

How to store in variable function returning value (kivy properties)

class Data(object):
def get_key_nicks(self):
'''
It returns key and nicks object
'''
file = open(self.key_address, 'rb')
key = pickle.load(file)
file.close()
file = open(self.nicks_address, 'rb')
nicks = pickle.load(file)
file.close()
return (key, nicks)
Above is the data api and function which i want to use in kivy
class MainScreen(FloatLayout):
data = ObjectProperty(Data())
key, nicks = ListProperty(data.get_key_nicks())
it gives error like: AttributeError: 'kivy.properties.ObjectProperty' object has no attribute 'get_key_nicks'
Properties are descriptors, which basically means they look like normal attributes when accessed from instances of the class, but at class level they are objects on their own. That's the nature of the problem here - at class level data is an ObjectProperty, even though if you access it from an instance of the class you'll get your Data() object that you passed in as the default value.
That said, I don't know what your code is actually trying to do, do you want key and nicks to be separate ListProperties?
Could you expand a bit more on what you're trying to do?
I think all you actually need to do is:
class MainScreen(FloatLayout):
data = ObjectProperty(Data())
def get_key_nicks(self):
return data.get_key_nicks()

Resources