I have a function 'draw_humans' in class 'TfPoseEstimator' in 'estimator.py' which is defined as:
def draw_humans:
global cocoDict
cocoDict = {}
cocoDict = dict(zip(a,zip(b,c)))
'''
'''
return (npimg, cocoDict, dist_dict)
I call this function in the main.py module and assign the returned values to variables like this:
image, cocoDict_clone, dist_dict_clone = TfPoseEstimator.draw_humans(image, humans, imgcopy=False)
But I get the error mentioned above.
Traceback (most recent call last):
File "run_webcam.py", line 306, in <module>
image, cocoDict_clone, dist_dict_clone = TfPoseEstimator.draw_humans(image, humans, imgcopy=False)
File "C:\Python\Python37\summer\PoseEstimation\tf_pose\estimator.py", line 772, in draw_humans
return (npimg, cocoDict, dist_dict)
NameError: name 'cocoDict' is not defined
[ WARN:1] terminating async callback
I have even tried to make it global but it did not work. Usually, it does work, can someone figure it out?
Actually, the problem was related to the scope of the variables (cocoDict in my case). This dictionary was initialized within the for loop but was being returned outside it. So, I declared it before the for loop and then after manipulating it within the for loop, returned it with no issues.
def draw_humans(npimg, humans, imgcopy=False):
global cocoDict
cocoDict = {}
for human in humans:
'''
'''
return (npimg, cocoDict, dist_dict)
I guess scope in Python is causing me a lot of efforts as I am from a C++ background.
Related
I am trying to create a generic function lifecycle handler in python.
Working in brief:
Logs the signature and return values.
Handles the exception with or without retry.
Provide cleanup in case of exception.
The issue which I encountered while doing the cleanup is as follows:
Function-based decorator:
def handler(exception=Exception,cleanup=None):
def func_wrapper(func):
def wrapper(*args,**kwargs):
response=None
try:
print(args)
response=func(*args,**kwargs)
except exception as ex:
print(f'Exception occurred:{str(ex)}\nCleaning up resources')
#Passing the object for cleanup, it fails for class based decorators as it does not passes self as argument
cleanup(args[0])
return response
return wrapper
return func_wrapper
The data which is supposed to be cleaned up is stored in the class instance and is cleaned based on the method provided.
For example:
Store some information using third party API.
In case of exception, the cleanup operation passed would invoke a
delete API.
class Test:
def __init__(self,data):
self.main_data=data
#handler(exception=Exception,cleanup=lambda x:print(f"Cleaning data:{x.main_data}"))
def test_data(self):
print(f'Data is :{self.main_data}')
i=1/0
Output:
Exception occurred:division by zero
Cleaning up resources
Cleaning:John Doe
I was more inclinded towards Class based decorator.
class LifeCycleHandler:
def __init__(self,*,func=None,exception=Exception,cleanup=None):
self.__exception=exception
self.__cleanup=cleanup
self.__func=func
def __call__(self,*args,**kwargs):
response=None
try:
print(args)
response=self.__func(*args,**kwargs)
except self.__exception as ex:
print(f'Exception occurred:{str(ex)}\n cleaning up resources')
#Passing the object for cleanup
self.__cleanup(args[0])
return response
def lifecycle_handler(exception=Exception,cleanup=None):
def wrapper(func):
response=LifeCycleHandler(func=func,exception=exception,cleanup=cleanup)
return response
return wrapper
With class based decorator with similar functionality i faced the following error:
()
Exception occurred:test_data() missing 1 required positional argument: 'self'
cleaning up resources
Traceback (most recent call last):
File "test.py", line 27, in __call__
response=self.__func(*args,**kwargs)
TypeError: test_data() missing 1 required positional argument: 'self'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test.py", line 54, in <module>
test.test_data()
File "test.py", line 31, in __call__
self.__cleanup(args[0])
IndexError: tuple index out of range
Can someone guide me regarding the the argument interpretation for callable classes?
If my comment correct, you could add __get__ to LifeCycleHandler.
def __get__(self, obj, type=None):
return functools.partial(self.__call__, obj)
This will make test_data become a non-data descriptor. I assume you already know descriptor. If not, it's definitely worth to check it.
Back to your question, from trace back, your assumed that python will help you pass the caller instance which is instance of Test as second argument to __call__. That's not true. However, that's true in __get__.
Your core logic (try/except block) needs are:
instance of Test, because you need access to main_data.
instance of LifeCycleHandler in, because you need access to your self.__func.
args in which isn't acceptable in __get__, but you could have them in __call__.
For example, you have test code below:
t = Test(123)
t.test_data()
t.test_data will invoke __get__. In its arguments, self is an instance of LifeCycleHandler and obj is t (instance of Test). __get__ returned a callable function(__call__) in which its first argument is partially feed by obj.
I'm trying to print method's name using __getattribute__
but I get typeerror everytime I called the method, and the method is not excuted, is there anyway to get rid of the type error and have the method excuted ?
class Person(object):
def __init__(self):
super()
def test(self):
print(1)
def __getattribute__(self, attr):
print(attr)
p = Person()
p.test()
The above code gives the error
test
Traceback (most recent call last):
File "test1.py", line 15, in <module>
p.test()
TypeError: 'NoneType' object is not callable
Is there anyway to print the method's name only without giving the error ?
I tried to catch typeError inside __getattribute__ method, but it doesn't work
Another question is, why it says None Type object is not callable here
Thank you !
Ps. I know I can catch the error when I call the method, I mean is there anyway to deal this error inside __getattribute method? since my goal is to print method's name everytime a method is called
Answering your second question first, why is it saying NoneType not callable.
When you call p.test() Python tries to lookup the test attribute of the p instance. It calls the __getattribute__ method that you've overridden which prints 'test' and then returns. Because you're not returning anything it implicitly returns None. p.test is therefore None and calling it gives the error you get.
So how do we fix this? Once you've printed the attribute name, you need to return the attribute you're after. You can't just call getattr(self, attr) or you'll end up in an infinite loop so you have to call the method that would have been called if you hadn't overridden it.
def __getattribute__(self, attr):
print(attr)
return super().__getattribute__(attr) # calls the original method
Why the following code produces an error
>>> object().foo = 'bar'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'object' object has no attribute 'foo'
while the next one works fine?
class A():
pass
A().foo = 'bar'
What is the exact difference between A and object? I believe o().foo = 'bar' leads to setattr('o', 'foo', 'bar') and this in turn results in o.__setattr__('foo', 'bar'). One would expect them to have identic __setattr__ methods since no overriding happens. Yet the outputs are different. Please explain why. What happens behind the scenes?
A similar pattern can be noticed for built-in functions and user-defined ones. I can't set my own attributes for let's say dict but it's perfectly ok to write (lambda:None).foo = 'bar'. What's going on here?
I've been having some issues with my code, you see I am a beginner at python programming and so I don't understand all the errors, So I would be quite happy for assistance down below is the code, which I have checked intensively just to find the error:
class Animal(object):
def __init__(self,legs,name):
def sleep(self,hours):
print("%s is sleeping for %d hours!" % (self.name,hours))
self.legs = legs
self.name = name
roscoe = Animal(4, "Canis Lupus Familiaris")
roscoe.name = ("Roscoe")
roscoe.sleep(4)
This is the Error:
Traceback (most recent call last):
File "class.py", line 9, in <module>
roscoe.sleep(4)
AttributeError: 'Animal' object has no attribute 'sleep'
You have a syntax error in the last line.
It should be:
roscoe.sleep(4)
instead of
roscue.sleep(4)
Giving more context since I see you're a begginner at Python. The traceback of Python interpreter (the "program" that runs Python code) tells you what happened. In this case, it says "name 'roscue' is not defined". This is usually a syntax error. Sometimes it can mean that you haven't defined that function. But in this case, it's the former.
Also, going a little bit further, you're probably going to get an error of indentation. In Python, you have to indent every block that you want to put together, either with tabs or with spaces.
Finally, think about your functions, you have to put them in order. Init is a function, and sleep is another function, so after each one you have a block. Different blocks should be indented separately. Here's how the code should look, but revise it instead of running it blindly.
class Animal(object):
def __init__(self,legs,name):
self.legs = legs
self.name = name
def sleep(self,hours):
print("%s is sleeping for %d hours!" % (self.name,hours))
roscoe = Animal(4, "Canis Lupus Familiaris")
roscoe.name = ("Roscoe")
roscoe.sleep(4)
I'm working with global vars but I get the error "NameError: name 'second_global_var' is not defined"
def my_function():
global first_global_var, second_global_var
if(first_global_var or second_global_var):
pass
Why it shows the error for 'second_global_var' and not for 'first_global_var', even if I define them each one with in its own line with global, the error persist for the variable 'second_global_var'.
The global statement does not create variables. It just makes Python look for them in the global namespace instead of the local namespace. In other words, saying global some_name tells Python to look for a global variable called some_name whenever you try to refer to some_name.
If that variable doesn't exist when you try to use it, Python will raise a NameError.
Inside the interpreter, you have:
>>> def my_function():
... global first_global_var, second_global_var
... if(first_global_var or second_global_var):
... pass
...
Then calling the function:
>>> my_function()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in my_function
NameError: global name 'first_global_var' is not defined
It complains about the first variable that it is not defined.