I have a situation in which I'm asked to read collections of database update instructions from a variety of sources. All sources will contain a primary key value so that the code that applies the updates to the database can find the correct record. The files will vary, however, in what additional columns are reported.
When I read and create my update instructions I must differentiate between an update in which a column (for instance, MiddleName) was provided but was empty (meaning no middle name and the field should be updated to NULL) and an update in which the MiddleName field was not included (meaning the update should not touch the middle name column at all).
The former situation (column provided but no value) seems appropriately represented by the None value. For the second situation, however, I'd like to have a NotInFile "value" that I can use similar to the way I use None.
Is the correct way to implement this as follows?
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'
I don't see anything particularly wrong with your implementation. however, 1 isn't necessarily the best sentinel value as it is a cached constant in Cpython. (e.g. -1+2 is 1 will return True). In these cases, I might consider using a sentinel object instance:
NotInFile = object()
python also provides a few other named constants which you could use if it seems appropriate: NotImplemented and Ellipsis come to mind immediately. (Note that I'm not recommending you use these constants ... I'm just providing more options).
No, using the integer one is a bad idea. It might work out in this case if MiddleName is always a string or None, but in general the implementation is free to intern integers, strings, tuples and other immutable values as it pleases. CPython does it for small integers and constants of the aforementioned types. PyPy defines is by value for integers and a few other types. So if MiddleName is 1, you're bound to see your code consider it not supplied.
Use an object instead, each new object has a distinct identity:
NotInFile = object()
Alternatively, for better debugging 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're paranoid, you could make it a proper singleton (ugly). If you need several such instances, you could rename the class into Sentiel or something, make the representation an instance variable and use multiple instances.
If you want type-checking, this idiom is now blessed by PEP 484 and supported by mypy:
from enum import Enum
class NotInFileType(Enum):
_token = 0
NotInFile = NotInFileType._token
If you are using mypy 0.740 or earlier, you need to workaround this bug in mypy by using typing.Final:
from typing import Final
NotInFile: Final = NotInFileType._token
If you are using Python 3.7 or earlier, you can use typing_extensions.Final from pip package typing_extensions instead of typing.Final
Related
I want to make sure, that one of the arguments, passed when class creation is of certain type. Here is an example:
from __future__ import annotations
from dataclasses import dataclass
#dataclass(frozen=True, order=True)
class ListItems:
items: list | str | int | ListItems
class PList:
def __init__(self, name: str, items: ListItems):
self.type = "list"
self.name = name
self.items = items
a = PList('asd', ['asd'])
The idea was next: items can only be list of string, int data type or other list of string and int, and it's nested. For example:
[] OK
[1,2,'asd'] OK
[[1,2,3],'asd',[]] OK
[{}] NOT OK
['test', [{}]] NOT OK
Is it possible to implement something like this in Python?
I am not really familiar with Python OOP, but from what I have found, there is no native implementation of interfaces and/or abstract class like in other programming languages.
PS:
The code you see, was just my attempt of implementation, it did not work.
def __init__(self, name: str, items: ListItems):
the items: ListItems bit is saying that items should be a ListItems object, it's not passing through the logic of what ListItems is doing, it's literally just comparing what type it is.
i don't have much experience with typing, but i think you're looking for items: list[str|int] note that for lists, there is the normal list type hint, and then there's also one in the typing library. not sure if there's a difference, i just know that the normal list type hint is lowercased (list and not List like in the typing library), and that it is relatively new (3.11 i think)
Short answer to your question Python is a dynamically typed language. It doesn’t know about the type of the variable until the code is run. So declaration is of no use. What it does is, It stores that value at some memory location and then binds that variable name to that memory container. And makes the contents of the container accessible through that variable name. So the data type does not matter. As it will get to know the type of the value at run-time.
Names are bound to objects at execution time by means of assignment statements, and it is possible to bind a name to objects of different types during the execution of the program. Functions and objects can be altered at runtime.
In a dynamically typed language, a variable is simply a value bound to
a name; the value has a type -- like "integer" or "string" or "list"
-- but the variable itself doesn't. You could have a variable which, right now, holds a number, and later assign a string to it if you need
it to change. In a statically typed language, the variable itself has
a type; if you have a variable that's an integer, you won't be able to
assign any other type of value to it later.
From the following point you will find that predefining the datatype explicitly in python code won't enforce it to only accept this type:
(since type errors are a small fraction of all the things that might go wrong in a program); as a result, programmers in dynamic languages rely on their test
suites to catch these and all other errors, rather than using a
dedicated type-checking compiler.
Check this reference for more info.
I'm not sure you even need the class listItems. Just use a simple if statement in your init method.
class PList:
def __init__(self, name, items):
self.type = 'list'
self.name = name
if type(items) is list or type(items) is str or type(items) is int:
self.items = items
Using the python typing system, I sometimes know the type of a variable or an expression because I have installed runtime checking to verify it. Is there a way to denote this with annotations?
For example, suppose I have a function combop which returns True if its argument is of class Combination. And further suppose that the class Combination has a field called tds.
if combop(x):
return f(x.tds)
else:
return f([])
In this example, I'd like to promise the checker that within the then part of the if, that x has type Combination, and x.tds makes sense.
An example of such a situation is line 172 of here python-rte. The IDE complains about d.tds and also n.s. I am supposing that there is a way to explain my intentions with type annotations, and the IDE would accept or verify my claim if possible.
The way this is done in some functional languages (e.g. Scala) is with pattern matching. Within a clause of a pattern match the type inferencer is able to restrict the type of certain variables. In some other languages (e.g. Common Lisp) there is a declare syntax which allows the programmer to give hints to the type inferencer which may or may not contribute a run-time overhead, depending on compiler settings.
Python 3.10 will introduce the new TypeGuard feature, which might provide you with what you're looking for. (The feature is also available through the typing_extensions module for Python <= 3.9.) A TypeGuard allows you to assert to the type-checker that an object is of a certain type. So, you could write a function like this:
from typing import TypeGuard, Any
def combop(obj: Any) -> TypeGuard[Combination]:
# Some code that returns `True` if the object is of type `Combination`, else `False`.
If you're more interested in the properties of your object (the "structural type" as opposed to the "nominal type" of your object), then you could use a TypeGuard to assert that your object conforms to a certain protocol.
from typing import Protocol, TypeGuard, Any
class CombinationsProto(Protocol):
tds: list[Any]
def combops(obj: Any) -> TypeGuard[CombinationsProto]:
# Some code here that returns `True` if the object has a `tds` attribute, else `False`.
As this is a new feature in the python-typing world, Python's major type-checkers are still working on support for this feature, especially with respect to some complex corner cases.
import typing
class Foo:
def __init__(self) -> None:
self.bar = "zebra" # will be of 'str' type
def give_me_something(): # no annotation here, can't tell what gets returned
if dict(): # an empty dict is always False, this is just an example, a real condition could be used
return []
else:
return Foo()
reveal_type(give_me_something())
reveal_type(typing.cast(Foo, give_me_something()))
$ mypy so69205255.py
so69205255.py:16: note: Revealed type is "Any"
so69205255.py:17: note: Revealed type is "so69205255.Foo"
I used MyPy to reproducibly check, but my IDE PyCharm also understands it : when I hover the variable name I assigned the expression to, it says that the first one is of type Union[list, Foo] while the second is of type Foo.
More info : see the docs
Does Python have a builtin type for representing symbolic values, when strings cannot be used?
A quick implementation of my own would look like
class Symbol:
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
Usecase
Such symbols are useful when a value – say a keyword argument or a list entry – needs to be initialized to a value that indicates that it hasn't been explicitly set.
If the values have constraints on allowed types, commonly None or some string would be used, but if any value is allowed, some other unique object is needed. My common method is to use an object() assigned to some private variable, but the symbol pattern is more convenient for debugging due to providing a meaningful printed representation.
As an alternative, one could use e.g. a tuple ('default value',) and compare against it with the is operator, but this wouldn't work e.g. for dictionary keys.
While the pattern is simple enough to copy/paste into each shell-script I am writing, a builtin solution with established behavior would be preferable.
Non-builtins
I know, that there are packages that provide a symbol type. An obvious one would be the symbol type of sympi, and there is https://pypi.org/project/SymbolType/. However, adding dependencies to avoid a 5-line pattern seems a heavy overkill, hence my question about a builtin type.
You could use the enum library:
https://docs.python.org/3/library/enum.html
I've been writing Python 2 code for ~ 3 years now, and although I've known about enums for a long time, we've started using them in our project (backported - pypi package enum34 ).
I'd like to understand when to use them.
One place where we started using them was to map some postgres database level enums to python enums. Therefore we have this enum class
class Status(enum.Enum):
active = 'active'
inactive = 'inactive'
But then when using these, we've ended up using them like this:
if value == Status.active.value:
...
And so using enums in this case is less helpful than just using a more simple class, like this
class Status(object):
active = 'active'
inactive = 'inactive'
Because we could use this more easily, like value == Status.active.
So far the only place I found this useful - though not as useful as I'd like - is in docstrings. Instead of explicitly saying that allowed values are 'active' and 'inactive', I can just declare that my formal parameter takes expects a member of the Status enum (more helpful when more statuses exist)
So I don't really know what would be their exact use case - I don't know how they're better than string constants.
In short: when to use enums?
A couple points:
Your Enum class can use str as a mixin.
Some database layers allow converting the stored data into Python data types.
For the first point:
class Status(str, Enum):
active = 'active'
inactive = 'inactive'
...
if value == Status.active:
...
For the second point:
I have little experience here, but I believe SQLAlchemy will do this.
I use Enum most often in GUI design. Imagine you have a radio button such as
This represents a list of fixed choices, so under the hood, it's well represented by an Enum. That is, if a user picks button 2, then Enum.Choice.Choice2 could be returned by some callback. This is better than returning an int 2 or string "choice 2", as there's nothing to validate these later. In other words, if you changed "choice 2" to "user choice 2", you could potentially break downstream components expecting the original symbol.
Think of Enum as a convenient shortcut to presenting a static set of choices, rather than creating boilerplate object classes.
I've found Enum's in Java (and other statically typed languages I presume) to be a bit more useful, as you can declare them in a method signature. For example, a method may have the signature,
public void (Enum.Choice, mychoice)
Instead of
public void (String, mychoice)
In the second case, users may have to know ahead of time that mychoice should be "foo" or "bar", but what if they pass in "baz", which is invalid. Using an Enum will ensure invalid input can't be passed to the method, as Enum.Choice would only have fields foo and bar. You couldn't create a baz Choice if you tried.
Sorry, I strayed into Java. Is this too off topic to be helpful?
The issue you see is because your ORM isn't mapping database values to your Enum object. If it did, you wouldn't have to deal with .value.
An alternative would be something like:
if Status(value) is Status.active: since the constructor creates an Enum from the given argument.
I have the following in a Python script:
setattr(stringRESULTS, "b", b)
Which gives me the following error:
AttributeError: 'str' object has no attribute 'b'
Can any-one telling me what the problem is here?
Don't do this. To quote the inestimable Greg Hewgill,
"If you ever find yourself using quoted names to refer to variables,
there's usually a better way to do whatever you're trying to do."
[Here you're one level up and using a string variable for the name, but it's the same underlying issue.] Or as S. Lott followed up with in the same thread:
"90% of the time, you should be using a dictionary. The other 10% of
the time, you need to stop what you're doing entirely."
If you're using the contents of stringRESULTS as a pointer to some object fred which you want to setattr, then these objects you want to target must already exist somewhere, and a dictionary is the natural data structure to store them. In fact, depending on your use case, you might be able to use dictionary key/value pairs instead of attributes in the first place.
IOW, my version of what (I'm guessing) you're trying to do would probably look like
d[stringRESULTS].b = b
or
d[stringRESULTS]["b"] = b
depending on whether I wanted/needed to work with an object instance or a dictionary would suffice.
(P.S. relatively few people subscribe to the python-3.x tag. You'll usually get more attention by adding the bare 'python' tag as well.)
Since str is a low-level primitive type, you can't really set any arbitrary attribute on it. You probably need either a dict or a subclass of str:
class StringResult(str):
pass
which should behave as you expect:
my_string_result = StringResult("spam_and_eggs")
my_string_result.b = b
EDIT:
If you're trying to do what DSM suggests, ie. modify a property on a variable that has the same name as the value of the stringRESULTS variable then this should do the trick:
locals()[stringRESULTS].b = b
Please note that this is an extremely dangerous operation and can wreak all kinds of havoc on your app if you aren't careful.