Defining my own non-like Python constant

I have a situation where I am asked to read collections of instructions for updating a database from various sources. All sources will contain the primary key value, so the code that applies the updates to the database can find the correct entry. However, the files will be different from what additional columns are reported.

When I read and create my update instructions, I have to distinguish between an update in which a column was provided (e.g. MiddleName) but was empty (this means that the middle name and field should not be updated to NULL) and the update in which was not is included in the MiddleName field (this means that the update should not touch the middle name column).

The first situation (a column, but not a value) is represented accordingly by the value None . However, for the second situation, I would like to have the value NotInFile ", which can be used in the same way as I use None.

Is this right to implement?

NotInFile = 1 class PersonUpdate(object): def __init__(self): self.PersonID = None self.FirstName = NotInFile self.MiddleName = NotInFile 

and then in another module

 import othermod upd = othermod.PersonUpdate() if upd.MiddleName is othermod.NotInFile: print 'Hey, middle name was not supplied' 
+4
source share
3 answers

I do not see anything special in your implementation. however, 1 not necessarily the best value for the sentinel value, since it is a cached constant in Cpython. (e.g. -1+2 is 1 will return True ). In such cases, I can consider an instance of the sentinel:

 NotInFile = object() 

python also provides several other named constants that you can use if it seems appropriate: NotImplemented and Ellipsis immediately come to mind. (Note that I do not recommend using these constants ... I just provide more parameters).

+8
source

No, using an integer is a bad idea. This can happen in this case, if MiddleName always a string or None , but, as a rule, the implementation is free for integers, strings, tuples and other immutable values. CPython does this for small integers and constants of the above types. PyPy defines is by value for integers and several other types. Therefore, if MiddleName is 1, you will definitely see that your code does not take it into account.

Use object instead, each new object has a different identifier:

 NotInFile = object() 

Alternatively, for a better debug output, define your own class:

 class NotInFileType(object): # __slots__ = () if you want to save a few bytes def __repr__(self): return 'NotInFile' NotInFile = NotInFileType() del NotInFileType # look ma, no singleton 

If you are paranoid, you can make it a suitable single (ugly). If you need several such instances, you can rename the class to Sentiel or something else, make a representation of the instance variable and use multiple instances.

+6
source

If you want to check the type, this idiom is now blessed with PEP 484 and supported by mypy :

 from enum import Enum from typing_extensions import Final class NotInFileType(Enum): token = 0 NotInFile: Final = NotInFileType.token 

Using typing_extensions.Final necessary because of this bug in mypy , fixed in the upcoming mypy 0.740.

+1
source

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


All Articles