I have this Python code...
class clss:
def __init__(self, d):
self.data = d
But every time I run it, I get this error...
AttributeError: 'clss' object has no attribute 'data'
How do I fix the error?
Your variable data is not defined anywhere, hence it cannot be assigned to self.data.
You'll want to pass data as an argument to __init__ instead of d:
class clss:
def __init__(self, data):
self.data = data
Related
import rospy
from sensor_msgs.msg import Imu
class ImuData:
def __init__(self):
#self.data = None
pass
def get_observation(self):
rospy.Subscriber('/imu', Imu, self.imu_callback)
imuData = self.data
print(imuData)
def imu_callback(self, msg):
self.data = msg.orientation
print(self.data)
if __name__ == '__main__':
rospy.init_node('gett_imu', anonymous= True)
idd = ImuData()
idd.get_observation()
In the above code, I would like to access self.data defined in imu_callback from get_observation function. The problem is I get error saying that ImuData has no attribute data.
How do I solve this issue?
Note: I feel that the question has to do with the python classes and not with Ros and rospy.
A couple of things are going on here. One, that was mentioned in the comment, is that you should be initializing your attributes inside __init__. The error your seeing is partially because of Python and the fact that self.data has not actually been initialized yet.
The second issue you have is where you setup the subscriber. This should also be done in __init__ and only once. Sensors will be publishing at a fairly constant rate, thus it takes time to actually receive any data on the topic. Also if you plan to call get_observation more than once you would create a new subscription, which you do not want.
Take the following code as a fixed example:
def __init__(self):
rospy.Subscriber('/imu', Imu, self.imu_callback)
self.data = None
def get_observation(self):
imuData = self.data
print(imuData)
Is there any way to refer to instance of a class from its metaclass every time an instance is created? I suppose I should use dunder _call_ method inside metaclass for that purpose.
I have the following code:
class meta(type):
def __call__(cls):
super().__call__()
#<--- want to get an object of A class here every time when instance of A class is created
class A(metaclass = meta):
def __init__(self, c):
self.c = 2
def test(self):
print('test called')
a1=A()
a2=A()
a3=A()
Also why when I implement __call__ method inside metaclass all created instances of my class became NoneType however when overring __call__ I used super().__call__()?
For example a4.test() returns AttributeError: 'NoneType' object has no attribute 'test'
The newly created instance is returned by super().__call__() - you hav to keep this value in a variable, use t for whatever you want and return it.
Otherwise, if the metaclass __call__ has no return statement, all instances are imediatelly de-referenced and destroyed, and the code trying to create instances just get None:
class meta(type):
def __call__(cls):
obj = super().__call__()
# use obj as you see fit
...
return obj
I have a class like
class MyClass:
def __init__(self):
self.will_be_a_numpy_array = None
def compute():
tmp = receive_data()
self.will_be_a_numpy_array = np.zeros(len(tmp))
# process each item in tmp, save result in corresponding element of self.will_be_a_numpy_array
Here __init__ method is vague regarding the type of self.will_be_a_numpy_array variable. It is unclear to fellow developer or compiler what type of variable should be expected. I cannot initialize variable with self.will_be_a_numpy_array = np.zeros(len(tmp)) because I haven't received data yet. What is the right way to articulate variable type in this case?
You can use the strategy that scikit-learn uses for their estimators, namely, you create the attribute when you receive the data and you use a trailing underscore to warn that this is an attribute that is not created at initialisation:
class MyClass:
def __init__(self):
pass
def process(self, data):
self.data_ = np.array(data)
def is_processed(self):
return hasattr(self, 'data_')
I want to delete an object using a function.
class Test():
def __init__(self, x):
self.x = x
foo = Test(5)
def delete(obj):
del obj
delete(foo)
print(foo)
In this code here, I am expecting it to give me an error on the last print statement, but it is printing my object, which I don't want. I want it to be deleted.
How would I go about doing so?
I will bite.
del obj deletes the locally-available reference to obj inside delete.
You will see it if you add any reference to obj inside delete:
def delete(obj):
del obj
obj
This causes the expected UnboundLocalError when calling delete.
Instead of del obj you can delete obj from the global namespace but you will have to use the name of the reference:
def delete(obj_name):
del globals()[obj_name]
then
class Test():
def __init__(self, x):
self.x = x
foo = Test(5)
def delete(obj_name):
del globals()[obj_name]
delete('foo')
print(foo)
NameError: name 'foo' is not defined
BUT Is there another goal you didn't explain? This on itself is a bit of a weird problem to be wanting to solve (ie XY problem). Why not let Python's GC handle the deletion of objects?
I'm having trouble accessing a superclass variable from a dictionary in the subclass.
The following code is a simplified example:
class SetStuff:
def __init__(self):
self.temperature = 0.0
def set_temp(self, temp):
self.temperature = temp
class DoStuff(SetStuff):
def __init__(self):
super().__init__()
self.info_dict = {"temp": {"current_temp": self.temperature}}
def print_stuff(self):
print("temp_var:", self.temperature)
print("dict:", self.info_dict)
test_stuff = DoStuff()
test_stuff.set_temp(12.1)
test_stuff.print_stuff()
The result of the final call is:
temp_var: 12.1
dict: {'temp': {'current_temp': 0.0}}
Whereas I expected the printed dictionary to contain 12.1. I can't seem to fathom what happens here and how I can fix this.
Any help would be greatly appreciated.
Look at where self.info_dict is set. It's in the __init__ so the value of self.temperature is indeed zero for current_temp because it's being set to the initial value of self.temperature