Thats my first question on Stackoverflow and im a totally Python beginner.
I want to write, to get firm with python, a small Backup-Programm, the main part is done, but now i want to make it a bit "portable" and use a Config file, which i want to Validate.
My class "getBackupOptions" should be give Back a validate dict which should be enriched with "GlobalOptions" and "BackupOption" so that i finally get an fully "BackupOption" dict when i call "getBackupOptions.BackupOptions".
My Question now is, (in this Example is it easy, because its only the Function which check if the Path should be Recursive searched or not) how to simplify my Code?
For each (possible) Error i must write a new "TryExcept" Block - Can i Simplify it?
Maybe is there another way to Validate Config Files/Arrays?
class getBackupOptions:
def __init__(self,BackupOption,GlobalOptions):
self.BackupOption = BackupOption
self.GlobalOptions = GlobalOptions
self.getRecusive()
def getRecusive(self):
try:
if self.BackupOption['recursive'] != None:
pass
else:
raise KeyError
except KeyError:
try:
if self.GlobalOptions['recursive'] != None:
self.BackupOption['recursive'] = self.GlobalOptions['recursive']
else:
raise KeyError
except KeyError:
print('Recusive in: ' + str(self.BackupOption) + ' and Global is not set!')
exit()
Actually i only catch an KeyError, but what if the the Key is there but there is something else than "True" or "False"?
Thanks a lot for you help!
You may try this
class getBackupOptions:
def __init__(self,BackupOption,GlobalOptions):
self.BackupOption = BackupOption
self.GlobalOptions = GlobalOptions
self.getRecusive()
def getRecusive(self):
if self.BackupOption.get('recursive') == 'True' and self.GlobalOptions.get('recursive') == 'True':
self.BackupOption['recursive'] = self.GlobalOptions['recursive']
else:
print('Recusive in: ' + str(self.BackupOption) + ' and Global is not set!')
exit()
Here get method is used, therefore KeyError will not be faced.
If any text other than True comes in the field it will be considered as False.
Related
The runtime keeps telling me:
expected an indented block
But I don't want write nothing inside my except block, I just want it to catch and swallow the exception.
Just write
pass
as in
try:
# Do something illegal.
...
except:
# Pretend nothing happened.
pass
EDIT: #swillden brings up a good point, viz., this is a terrible idea in general. You should, at the least, say
except TypeError, DivideByZeroError:
or whatever kinds of errors you want to handle. Otherwise you can mask bigger problems.
For those who are very unclear as to why you would want to do this. Here is an example where I initially thought that an empty block would be a good idea:
def set_debug_dir(self, debug_dir=None):
if debug_dir is None:
debug_dir = self.__debug_dir
elif isinstance(debug_dir, (Path, str)):
debug_dir = debug_dir # this is my null operation
elif isinstance(debug_dir, list):
debug_dir = functools.reduce(os.path.join, debug_dir)
else:
raise TypeError('Unexpected type for debug_dir: {}'.format(type(debug_dir).__name__))
But it would be more clear to reorganize the statement:
def set_debug_dir(self, debug_dir=None):
if debug_dir is None:
debug_dir = self.__debug_dir
elif isinstance(debug_dir, list):
debug_dir = functools.reduce(os.path.join, debug_dir)
elif not isinstance(debug_dir, (Path, str)):
raise TypeError('Unexpected type for debug_dir: {}'.format(type(debug_dir).__name__))
I've never done this in more permanent code, but I frequently do it as a placeholder
if some_expression:
True
else:
do_something(blah)
Just sticking a True in there will stop the error. Not sure if there's anything bad about this.
I need to check, whether variable is defined or not. If it is not, then this variable should be created as empty string.
I want to do it by try and it works fine:
try:
ident
except:
ident = ''
But I need to do that using a function, coz I will do that many, many times and it will became unreadable.
Doing it like below can't work, coz it will not go into the function, if ident does not exist.
def absence_of_tag(ident):
try:
ident
except:
return ''
I was also trying to do it with *args, like that:
def absence_of_tag(*args):
try:
args
except:
return ''
and then call it by:
ident = absence_of_tag(ident)
I thought, it will go into the except in function, but still it gave me NameError: name 'ident' is not defined
Do you have any idea how to do that? Is it even possible?
If you want a one-liner, you can perhaps go with:
ident= ident if ident else ' '
EDIT: This also worked for me:
f=lambda x: x if x else ' '
c=8
f(c)
# output: 8
f(d)
# NameError: name 'd' is not defined
I have a dictionary list of size ~250k in python (i.e 250k dictionaries in a list), which I try to process as shown below. The aim is to clean up the dictionary and return an iterable at the end. So, I have something like this:
def check_qs(dict_list_in):
try:
del_id=[]
for i in dict_list_in:
tmp=i["get_url"][0]
if i["from"][0]=="var0":
try:
URLValidator()(tmp)
except:
del_id.append( i["id"] )
elif i["from"][0]=="var1":
try:
URLValidator()( tmp.split("\"")[1] )
except:
del_id.append( i["id"] )
elif i["from"][0]=="var2":
try:
URLValidator()( tmp.split("\'")[1] )
except:
del_id.append( i["id"] )
else:
del_id.append( i["id"] )
gc.collect()
result = filter(lambda x: x['id'] not in del_id,dict_list_in)
return result
except:
return dict_list_in
What I am doing above, is checking each dictionary in ths list for some condition, and if this fails, I get the id and then use filter to delete those dictionaries specific from the list.
At the moment, this takes a long time to run - and I was wondering if there were any obvious optimizations I am missing out on. I think at the moment the above code is too naive.
I made a couple changes. I put the validation instance out of the loop so that you don't have to initialize it every time. If it's required to instantiate every time, just move it into the try accept block. I also changed from deleting items in the original list, to appending the items to a new list that you want, removing the need for a filter. I also moved the validation out of the if statements so that if you hit the else statement you don't have to run the validation. Look at the logic of the if statements, it is the same as yours. It appears that you are using django, but if you aren't change the except to except Exception.
from django.core.exceptions import ValidationError
def check_qs(dict_list_in):
new_dict_list = []
validate = URLValidator()
for i in dict_list_in:
test_url = i["get_url"][0]
if i["from"][0] == "var0":
pass
elif i["from"][0] == "var1":
test_url = test_url.split("\"")[1]
elif i["from"][0] == "var2":
test_url = test_url.split("\'")[1]
else:
continue
try:
validate(test_url)
# If you aren't using django you can change this to 'Exception'
except ValidationError:
continue
new_dict_list.append(i)
return new_dict_list
i have to check if the content of some variable are of some specific type (it is a sanity check i want to implement). If each one of these is not of the specified type then the program has to abort.
I'm not experienced in python, i've a glance to the official guide on the web where it is stated that it is possible to define own exceptions by class implementation. I don't know if that would be hard or not, but since i don't have to do something particularly complicated is it possible to do that in a simple way?
Update
I've implemented the exception int exception in the following way:
class TypeCheckingException(Exception):
def __init__(self,type_in,type_exp):
self.type_in = type_in
self.type_exp = type_exp
The specific line of the implementation its use are:
try:
if isinstance(var1,str) == 0:
raise TypeCheckingException(type(var1),str)
if isinstance(var2,str) == 0:
raise TypeCheckingException(type(var2),str)
if isinstance(var3,int) == 0:
raise TypeCheckingException(type(var3),int)
if isinstance(var4,int) == 0:
raise TypeCheckingException(type(var4),int)
if isinstance(var5,str) == 0:
raise TypeCheckingException(type(var5),str)
if isinstance(var6,float) == 0:
raise TypeCheckingException(type(var6),float)
except TypeCheckingException, tce:
print "Type expected input " + str(tce.type_in) + " while type expected is " + str(tce.type_exp) + "."
In this case works, but the error output is quite verbose... i'd like to make it shorter...
Any clue?
You want to use isinstance(variable, type).
>>> a = 'str'
>>> isinstance(a, str)
True
You won't need to use exception handling with this route. You can check for instance type, then exit, if necessary.
I have something like this using BeautifulSoup:
for line in lines:
code = l.find('span', {'class':'boldHeader'}).text
coded = l.find('div', {'class':'Description'}).text
definition = l.find('ul', {'class':'definitions'}).text
print code, coded, def
However, not all elements exist at all times. I can enclose this in a try except so that it does not break the program execution like this:
for line in lines:
try:
code = l.find('span', {'class':'boldHeader'}).text
coded = l.find('div', {'class':'Description'}).text
definition = l.find('ul', {'class':'definitions'}).text
print code, coded, def
except:
pass
But how I execute the statements in a greedy fashion? For instance, if there are only two elements available code and coded, I just want to get those and continue with the execution. As of now, even if code and coded exist, if def does not exist, the print command is never executed.
One way of doing this is to put a try...except for every statement like this:
for line in lines:
try:
code = l.find('span', {'class':'boldHeader'}).text
except:
pass
try:
coded = l.find('div', {'class':'Description'}).text
except:
pass
try:
definition = l.find('ul', {'class':'definitions'}).text
except:
pass
print code, coded, def
But this is an ugly approach and I want something cleaner. Any suggestions?
How about capture the "ugly" code in a function, and just call the function as needed:
def get_txt(l,tag,classname):
try:
txt=l.find(tag, {'class':classname}).text
except AttributeError:
txt=None
return txt
for line in lines:
code = get_txt(l,'span','boldHeader')
coded = get_txt(l,'div','Description')
defn = get_txt(l,'ul','definitions')
print code, coded, defn
PS. I changed def to defn because def is a Python keyword. Using it as a variable name raises a SyntaxError.
PPS. It's not a good practice to use bare exceptions:
try:
....
except:
...
because it almost always captures more that you intend. Much better to be explicit about what you want to catch:
try:
...
except AttributeError as err:
...
First of all, you can test for None instead of catching an exception. l.find should return None if it doesn't find your item. Exceptions should be reserved for errors and really extraordinary situations.
Second thing you can do is to create an array of all HTML elements you want to check and then have a nested for loop. Since it's been a while since I've used python, I will outline the code and then (hopefully) edit the answer when I test it.
Something like:
elementsToCheck = [
[ 'span', {'class':'boldHeader'} ],
[ 'div', {'class':'Description'} ],
[ 'ul', {'class':'definitions'} ]]
concatenated = ''
for line in lines:
for something in elementsToCheck
element = l.find(something[0], something[1])
if element is not None
concatenated += element.text
print concatenated
Obviously the code above won't work, but you should get the idea. :)