Python checks for one or more None values ​​and knows which ones

I have a Python application with a Firebase database backend.

When I retrieve data from my database, I want to check if these values ​​are (if not, this means that the database is somehow damaged, because there are no credential fields)

My current implementation is as follows:

self.foo = myDbRef.get('foo') self.bar = myDbRef.get('bar') self.bip = myDbRef.get('bip') self.plop = myDbRef.get('plop') if self.foo is None or self.bar is None or self.bip is None or self.plop is None: self.isValid = False return ErrorCode.CORRUPTED_DATABASE 

This works great, compact, but has a serious problem: I will get information that the database is damaged, but not that the field is missing (there can only be one of them, or more, or all!)

The idiomatic approach should be

 if self.foo is None: self.isValid = False return ErrorCode.CORRUPTED_DATABASE, "FOO IS MISSING" # could be a string, an enum value, whatever, I have the information if self.bar is None: self.isValid = False return ErrorCode.CORRUPTED_DATABASE, "BAR IS MISSING" if self.bip is None: self.isValid = False return ErrorCode.CORRUPTED_DATABASE, "BIP IS MISSING" 

But it is not beautiful, it does not factorize (all my functions "init from db" use the same template ... I do not want to multiply my number of lines by 10 times for this case).

This is not a "100% python" question, but I hope langage has something for me to handle it like a boss (this is python: it usually does!)

+5
source share
4 answers

You can extract the checks to the generator and leave the checkbox and return checked. Outside.

 def invalid_fields(): if self.foo is None: yield "FOO" if self.bar is None: yield "BAR" if self.bip is None: yield "BIP" invalid = list(invalid_fields()) if invalid: self.isValid = False return ErrorCode.CORRUPTED_DATABASE, "MISSING {}".format(", ".join(invalid)) 

This has the advantage that you talk about all the missing fields, if there are more.

+1
source

I created a class containing some of your functions that I cannot access. I also made ErrorCode a string as a hack, as this is not defined in my tools, and I'm not sure how you want the None names to be returned with / next to ErrorCode.

Build a dict names and values, make sure the dict does not contain None values, and if so, return the keys:

 myDbRef = {'foo' : None, 'bar': 1, 'bip': 2, 'plop': 3} class Foo(): def __init__(self): self.foo = myDbRef.get('foo') self.bar = myDbRef.get('bar') self.bip = myDbRef.get('bip') self.plop = myDbRef.get('plop') def check(self): temp_dict = {} for key in ['foo','bar','bip','plop']: temp_dict[key] = myDbRef.get(key) vals = {k:v for k,v in temp_dict.items() if v is None} if vals: self.isValid = False return ("ErrorCode.CORRUPTED_DATABASE", [k for k in vals.keys()]) f = Foo() print(f.check()) 

Result: ('ErrorCode.CORRUPTED_DATABASE', ['foo'])

0
source

Use function and loop:

 def checknone(**things_with_names): for name, thing in things_with_names.items(): if thing is None: return ErrorCode.CORRUPTED_DATABASE, name + " IS MISSING" return True 

And use as such:

 result = checknone(foo=self.foo, bar=self.bar, bip=self.bip, plop=self.plop) if result is not True: self.isValid = False return result 

To get the maximum gain, put it as a class method that you will mix with all your classes that use this. That way he can also install isValid .

0
source

You can dynamically create and search instance attributes like this:

 class Foo(): def __init__(self): # First, define the list of attributes you want to look for and an empty list of errors self.attrbs = ['foo','bar','bip','plop'] self.errors = [] # Iterate through the attributes list for attrb in self.attrbs: # Create and assign self.foo to MyDbRef.get('foo'), etc self.__dict__[attrb] = myDbRef.get(attrb) # Check if attribute is empty, if so, add to error if not self.__dict__[attrb]: self.errors.append(attrb.upper()) # Check if there are any errors if self.errors: self.is_valid = False return (ErrorCode.CORRUPTED_DATABASE, "MISSING {errs}".format(errs='/'.join(self.errors))) else: self.is_valid = True 
0
source

Source: https://habr.com/ru/post/1275323/


All Articles