I made the following simple class in Visual studio community edition:
class Check(object):
def __init__(self):
self.t = 5
but when run
from Check import Check
try:
print(Check.t)
except Exception as Err:
print(str(Err))
or
import Check
try:
print(Check.t)
except Exception as Err:
print(str(Err))
I get the error of:
The object 'Check' has no attribute 't'
It is also weird because the keyword 'self' is not shown as Python keyword or Buildin func.
You've gotta instantiate the Object of Check before being able to access it.
This can be done by the following
from Check import Check
try:
print(Check().t)
except Exception as Err:
print(str(Err))
When you try to call Check.t it's trying to access the class element 't' which is non existent.
The information regarding visual studio community is redundant here.
The problem lies with how you're defining and calling your class.
You've created a class(the blueprint) but haven't created any instance (actual object) while calling the attribute (variable t).
Let's say you have a module named check.py where you've defined your simple class.
# check.py
class Check:
def __init__(self):
self.t = 5
Now import the class Check from module check.py
from check import Check
# create an instance of the class
ins = Check()
# access and print the attribute
try:
att = ins.t
print(att)
except Exception as err:
print(str(err))
Related
I`m trying to handle the exception 'ProfileNotExistsException' and the code is as follows:
try:
profile = instaloader.Profile.from_username(bot.context, followees[i])
#Other statements
except ProfileNotExistsException:
print('exception')
But This NameError is occurring.
NameError Traceback (most recent call last)
Input In [11], in <cell line: 2>()
6 allfolloweesDataList.append((profile.userid,profile.username,profile.full_name,profile.followers,profile.followees,profile.is_verified,profile.biography,profile.external_url))
7 print(i,end=',')
----> 8 except ProfileNotExistsException:
9 print('exception')
NameError: name 'ProfileNotExistsException' is not defined
How can I define a name for an exception like this?
Looking at the source code for the instaloader package, I believe this is what you are looking for:
from instaloader.exceptions import ProfileNotExistsException
try:
profile = instaloader.Profile.from_username(bot.context, followees[i])
...
except ProfileNotExistsException:
print('exception')
instaloader.exceptions
instaloader.exceptions.ProfileNotExistsException
Your question is not clear enough. There are three options.
I. You don't have such an existing class
class ProfileNotExistsException(ValueError):
def __init__(self):
pass
def __str__(self) -> str:
return 'Profile doesn\'t exist!'
You need to create such a class, and based on its name, it should extend ValueError. Then you can catch it.
II. There is such a class
Just import it, or in your case it might be instaloader.ProfileNotExistsException
III. You actually don't want to catch only this exception
Use
try:
pass #...
except BaseException: # ValueError IndexError...
pass #...
Thanks to all the contributors. The real problem was that the exception 'ProfileNotExistsException' was not defined in the code. We can handle the common exceptions easily as they are already defined check the list of a built-in exceptions.
So, If the exception is not the one from the built-in exceptions, we have to define this exception in our code before calling it. Thanks
Let's say I want to set functions for each classes in module Named 'MacroMethods'. So I've set up singledispatch after seeing it in 'Fluent Python' like this:
#singledispatch
def addMethod(self, obj):
print(f'Wrong Object {str(obj)} supplied.')
return obj
...
#addMethod.register(MacroMethods.Wait)
def _(self, obj):
print('adding object wait')
obj.delay = self.waitSpin.value
obj.onFail = None
obj.onSuccess = None
return obj
Desired behavior is - when instance of class 'MacroMethods.Wait' is given as argument, singledispatch runs registered function with that class type.
Instead, it runs default function rather than registered one.
>>> Wrong Object <MacroMethods.Wait object at 0x0936D1A8> supplied.
However, type() clearly shows instance is class 'MacroMethods.Wait', and dict_keys property also contains it.
>>> dict_keys([<class 'object'>, ..., <class 'MacroMethods.Wait'>])
I suspect all custom classes I made count as 'object' type and don't run desired functions in result.
Any way to solve this problem? Entire codes are here.
Update
I've managed to mimic singledispatch's actions as following:
from functools import wraps
def state_deco(func_main):
"""
Decorator that mimics singledispatch for ease of interaction expansions.
"""
# assuming no args are needed for interaction functions.
func_main.dispatch_list = {} # collect decorated functions
#wraps(func_main)
def wrapper(target):
# dispatch target to destination interaction function.
nonlocal func_main
try:
# find and run callable for target
return func_main.dispatch_list[type(target)]()
except KeyError:
# If no matching case found, main decorated function will run instead.
func_main()
def register(target):
# A decorator that register decorated function to main decorated function.
def decorate(func_sub):
nonlocal func_main
func_main.dispatch_list[target] = func_sub
def register_wrapper(*args, **kwargs):
return func_sub(*args, **kwargs)
return register_wrapper
return decorate
wrapper.register = register
return wrapper
Used like:
#state_deco
def general():
return "A's reaction to undefined others."
#general.register(StateA)
def _():
return "A's reaction of another A"
#general.register(StateB)
def _():
return "A's reaction of B"
But still it's not singledispatch, so I find this might be inappropriate to post this as answer.
I wanted to do similar and had the same trouble. Looks like we have bumped into a python bug. Found a write-up that describes this situation.
Here is the link to the Python Bug Tracker.
Python 3.7 breaks on singledispatch_function.register(pseudo_type), which Python 3.6 accepted
I'm using Python 3.7 and PyCharm 2019.1.3, I've made a subclass of UserString and althought the documentation clearly states I should be able to access the underlying string with myinstance.data PyCharm shows me an Unresolved attribute reference 'data' for class 'Token'.
Here's my subclass:
from collections import UserString
class Token(UserString):
def __init__(self, value, is_emoji: bool):
# if it's not an emoji and a title we lower-case the value
UserString.__init__(self, value.lower() if not is_emoji and value.istitle() else value)
self.is_emoji: bool = is_emoji
if __name__ == '__main__':
token = Token("Sauce", False)
print(token.data)
is it a PyCharm bug or am I doing something wrong ?
Since I can correctly print(token.data) in your example, this indeed must be a bug in PyCharm.
You can try to sidestep it by using super which likely would trigger a different code analysis path and discover the .data member. Did not try it, though.
I'm trying to wrap all methods of an existing Class (not of my creation) into a try/except suite. It could be any Class, but I'll use the pandas.DataFrame class here as a practical example.
So if the invoked method succeeds, we simply move on. But if it should generate an exception, it is appended to a list for later inspection/discovery (although the below example just issues a print statement for simplicity).
(Note that the kinds of data-related exceptions that can occur when a method on the instance is invoked, isn't yet known; and that's the reason for this exercise: discovery).
This post was quite helpful (particularly #martineau Python-3 answer), but I'm having trouble adapting it. Below, I expected the second call to the (wrapped) info() method to emit print output but, sadly, it doesn't.
#!/usr/bin/env python3
import functools, types, pandas
def method_wrapper(method):
#functools.wraps(method)
def wrapper(*args, **kwargs): #Note: args[0] points to 'self'.
try:
print('Calling: {}.{}()... '.format(args[0].__class__.__name__,
method.__name__))
return method(*args, **kwargs)
except Exception:
print('Exception: %r' % sys.exc_info()) # Something trivial.
#<Actual code would append that exception info to a list>.
return wrapper
class MetaClass(type):
def __new__(mcs, class_name, base_classes, classDict):
newClassDict = {}
for attributeName, attribute in classDict.items():
if type(attribute) == types.FunctionType: # Replace it with a
attribute = method_wrapper(attribute) # decorated version.
newClassDict[attributeName] = attribute
return type.__new__(mcs, class_name, base_classes, newClassDict)
class WrappedDataFrame2(MetaClass('WrappedDataFrame',
(pandas.DataFrame, object,), {}),
metaclass=type):
pass
print('Unwrapped pandas.DataFrame().info():')
pandas.DataFrame().info()
print('\n\nWrapped pandas.DataFrame().info():')
WrappedDataFrame2().info()
print()
This outputs:
Unwrapped pandas.DataFrame().info():
<class 'pandas.core.frame.DataFrame'>
Index: 0 entries
Empty DataFrame
Wrapped pandas.DataFrame().info(): <-- Missing print statement after this line.
<class '__main__.WrappedDataFrame2'>
Index: 0 entries
Empty WrappedDataFrame2
In summary,...
>>> unwrapped_object.someMethod(...)
# Should be mirrored by ...
>>> wrapping_object.someMethod(...)
# Including signature, docstring, etc. (i.e. all attributes); except that it
# executes inside a try/except suite (so I can catch exceptions generically).
long time no see. ;-) In fact it's been such a long time you may no longer care, but in case you (or others) do...
Here's something I think will do what you want. I've never answered your question before now because I don't have pandas installed on my system. However, today I decided to see if there was a workaround for not having it and created a trivial dummy module to mock it (only as far as I needed). Here's the only thing in it:
mockpandas.py:
""" Fake pandas module. """
class DataFrame:
def info(self):
print('pandas.DataFrame.info() called')
raise RuntimeError('Exception raised')
Below is code that seems to do what you need by implementing #Blckknght's suggestion of iterating through the MRO—but ignores the limitations noted in his answer that could arise from doing it that way). It ain't pretty, but as I said, it seems to work with at least the mocked pandas library I created.
import functools
import mockpandas as pandas # mock the library
import sys
import traceback
import types
def method_wrapper(method):
#functools.wraps(method)
def wrapper(*args, **kwargs): # Note: args[0] points to 'self'.
try:
print('Calling: {}.{}()... '.format(args[0].__class__.__name__,
method.__name__))
return method(*args, **kwargs)
except Exception:
print('An exception occurred in the wrapped method {}.{}()'.format(
args[0].__class__.__name__, method.__name__))
traceback.print_exc(file=sys.stdout)
# (Actual code would append that exception info to a list)
return wrapper
class MetaClass(type):
def __new__(meta, class_name, base_classes, classDict):
""" See if any of the base classes were created by with_metaclass() function. """
marker = None
for base in base_classes:
if hasattr(base, '_marker'):
marker = getattr(base, '_marker') # remember class name of temp base class
break # quit looking
if class_name == marker: # temporary base class being created by with_metaclass()?
return type.__new__(meta, class_name, base_classes, classDict)
# Temporarily create an unmodified version of class so it's MRO can be used below.
TempClass = type.__new__(meta, 'TempClass', base_classes, classDict)
newClassDict = {}
for cls in TempClass.mro():
for attributeName, attribute in cls.__dict__.items():
if isinstance(attribute, types.FunctionType):
# Convert it to a decorated version.
attribute = method_wrapper(attribute)
newClassDict[attributeName] = attribute
return type.__new__(meta, class_name, base_classes, newClassDict)
def with_metaclass(meta, classname, bases):
""" Create a class with the supplied bases and metaclass, that has been tagged with a
special '_marker' attribute.
"""
return type.__new__(meta, classname, bases, {'_marker': classname})
class WrappedDataFrame2(
with_metaclass(MetaClass, 'WrappedDataFrame', (pandas.DataFrame, object))):
pass
print('Unwrapped pandas.DataFrame().info():')
try:
pandas.DataFrame().info()
except RuntimeError:
print(' RuntimeError exception was raised as expected')
print('\n\nWrapped pandas.DataFrame().info():')
WrappedDataFrame2().info()
Output:
Unwrapped pandas.DataFrame().info():
pandas.DataFrame.info() called
RuntimeError exception was raised as expected
Wrapped pandas.DataFrame().info():
Calling: WrappedDataFrame2.info()...
pandas.DataFrame.info() called
An exception occurred in the wrapped method WrappedDataFrame2.info()
Traceback (most recent call last):
File "test.py", line 16, in wrapper
return method(*args, **kwargs)
File "mockpandas.py", line 9, in info
raise RuntimeError('Exception raised')
RuntimeError: Exception raised
As the above illustrates, the method_wrapper() decoratored version is being used by methods of the wrapped class.
Your metaclass only applies your decorator to the methods defined in classes that are instances of it. It doesn't decorate inherited methods, since they're not in the classDict.
I'm not sure there's a good way to make it work. You could try iterating through the MRO and wrapping all the inherited methods as well as your own, but I suspect you'd get into trouble if there were multiple levels of inheritance after you start using MetaClass (as each level will decorate the already decorated methods of the previous class).
I need to get the information contained in the exception. This is the code I use.
try:
result = yield user_collection.insert_many(content, ordered=False)
except BulkWriteError as e:
print (e)
And in my test when I get into the except with this line,
self.insert_mock.side_effect = [BulkWriteError('')]
it returns me
batch op errors occurred
instead of a MagicMock or a Mock.
How can I mock the BulkWriteError and give it a default return_value and see it when I use print(e)?
Something like this should allow you to test your print was called correctly.
import builtins # mockout print
class BulkWriteErrorStub(BulkWriteError):
''' Stub out the exception so you can bypass the constructor. '''
def __str__:
return 'fake_error'
#mock.patch.object('builtins', 'print')
def testRaisesBulkWrite(self, mock_print):
...
self.insert_mock.side_effect = [BuilkWriteErrorStub]
with self.assertRaises(...):
mock_print.assert_called_once_with('fake_error')
I haven't tested this so feel free to edit it if I made a mistake.