Using Python 3.4 I want to test whether an Enum class contains a member with a certain name.
Example:
class Constants(Enum):
One = 1
Two = 2
Three = 3
print(Constants['One'])
print(Constants['Four'])
gives:
Constants.One
File "C:\Python34\lib\enum.py", line 258, in __getitem__
return cls._member_map_[name]
KeyError: 'Four'
I could catch the KeyError and take the exception as indication of existence but maybe there is a more elegant way?
You could use Enum.__members__ - an ordered dictionary mapping names to members:
In [12]: 'One' in Constants.__members__
Out[12]: True
In [13]: 'Four' in Constants.__members__
Out[13]: False
I would say this falls under EAFP (Easier to ask for forgiveness than permission), a concept that is relatively unique to Python.
Easier to ask for forgiveness than permission. This common Python coding style assumes the existence of valid keys or attributes and catches exceptions if the assumption proves false. This clean and fast style is characterized by the presence of many try and except statements. The technique contrasts with the LBYL style common to many other languages such as C.
This contrasts with LBYL (Look before you leap), which is what I think you want when you say you are looking for "a more elegant way."
Look before you leap. This coding style explicitly tests for pre-conditions before making calls or lookups. This style contrasts with the EAFP approach and is characterized by the presence of many if statements.
In a multi-threaded environment, the LBYL approach can risk introducing a race condition between “the looking” and “the leaping”. For example, the code, if key in mapping: return mapping[key] can fail if another thread removes key from mapping after the test, but before the lookup. This issue can be solved with locks or by using the EAFP approach.
Therefore based on the documentation, it is actually better to use try/except blocks for your problem.
TL;DR
Use try/except blocks to catch the KeyError exception.
Could use the following to test if the name exists:
if any(x for x in Constants if x.name == "One"):
# Exists
else:
# Doesn't Exist
Of use x.value to test for the enum value:
if any(x for x in Constants if x.value == 1):
# Exists
else:
# Doesn't Exist
In order to improve legibility, you can put these suggestions above as class method.
For instance:
class Constants(Enum):
One = 1
Two = 2
Three = 3
#classmethod
def has_key(cls, name):
return name in cls.__members__ # solution above 1
# return any(x for x in cls if x.name == name) # or solution above 2
In order to use:
In [6]: Constants.has_key('One')
Out[6]: True
In [7]: Constants.has_key('Four')
Out[7]: False
Reading the source code for the Enum class:
def __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1):
"""Either returns an existing member, or creates a new enum class.
So, based on the docstring notes, a Pythonic way of checking membership would be:
from enum import Enum
class TestEnum(Enum):
TEST = 'test'
def enum_contains(enum_type, value):
try:
enum_type(value)
except ValueError:
return False
return True
>>> enum_contains(TestEnum, 'value_doesnt_exist')
False
>>> enum_contains(TestEnum, 'test')
True
Related
I have three variables that are closely tied together and I do not want to pass separately every time I call a function. What is the proper way to bundle them.
Context: The purpose of the variables is to keep track of some properties of a document while I am reading it word by word.
My current approach is to bundle them in a class:
class MarkdownIsOpen(object):
def __init__(self):
self.ChapterOpen = False
self.SectionOpen = False
self.ArticleOpen = False
But this seems a bit wrong to me, as I do not intend to add any methods or other functionalities.
A namedtuple would be perfect if it were mutable.
What would be the proper (most pythonic) way to bundle the three variables?
Use a dataclass:
#dataclass
class MarkdownIsOpen:
ChapterOpen: bool = False
SectionOpen: bool = False
ArticleOpen: bool = False
Or:
MarkdownIsOpen = make_dataclass('MarkdownIsOpen', ['ChapterOpen', 'SectionOpen', 'ArticleOpen'])
Note that this requires Python 3.7.
If you're using Python <= 3.6, then an ordinary class will do as well. Classes are not expensive, and they provide a hint to the user that your function does not expect any old dict-like, but a special container with the following attributes.
Compare this to, for example, C's struct or Scala's case class, which serve largely the same purpose.
Also, you can even override __slots__ and/or __getitem__ to allow dict-like access, and prevent the addition of new attributes:
class MarkdownIsOpen:
__slots__ = ('ChapterOpen', 'SectionOpen', 'ArticleOpen')
def __init__(self):
self.ChapterOpen = False
self.SectionOpen = False
self.ArticleOpen = False
def __getattr__(self, key):
return getattr(self, key)
def __setattr__(self, key, value):
setattr(self, key, value)
Example:
m = MarkdownIsOpen()
m['ChapterOpen'] = True
print(m['SectionOpen'])
m['Nonexistent'] = False
Output:
False
AttributeError: 'MarkdownIsOpen' object has no attribute 'Nonexistent'
You can use dataclasses.
#dataclass
class MarkdownIsOpen:
ChapterOpen: bool = False
SectionOpen: bool = False
ArticleOpen: bool = False
May take a look at this question: Existence of mutable named tuple in Python?
With two nice answers: recordclass
and namedlist of mutable alternatives to named tuples
You could use a simple named tuple or a simple dictionary for that purpose, if you really never need to define any methods on the class.
Python is a language in which the following is possible:
>>> class A(object):
... def __eq__(self, _):
... return True
...
>>> a = A()
>>> a == "slfjghsjdfhgklsfghksjd"
True
>>> a == -87346957234576293847658734659834628572384657346573465
True
>>> a == None
True
>>> a is None
False
Other things, like gt and lt are also "overloadable"1 in this way, and this is a great feature, in my opinion.
I'm curious if the = assignment operator is also "overloadable"1 in a similar kind of fashion, or if I'd have to recompile Python into NotPython to do this.
(As far as I know, classes and objects don't implement some __assign__ method; that's implemented with the C bytecode runner/compiler.)
Specifically, I want to implement an LL(k) parser by iterating on a token list, without using an iterator such that I can change the iterator's index arbitrarily to jump to a given token.
The catch is that on a given cycle of the loop, if I've already arbitrarily modified the index in preparation for the next cycle (something I'll surely do a lot) the last thing I want to do is mess up that variable by adding one to it as if it hadn't been changed.
Probably the easiest, simplest solution to this is to have a flag that gets set on jumps and which is reset to False every cycle, but this can and will introduce tiny hiding bugs I'd like to avoid ahead of time. (See here for what I mean -- this is the pathetic iterative LL(1) parser I'm rewriting, and I want its reincarnation to be somewhat maintainable and/or readable.)
The flag solution:
idx = 0
while True:
jmpd = False
# maybe we jumped, maybe we didn't; how am I to know!?!?
if jmpd == False:
idx += 1
Great! One big drawback: at each possible branch resulting in an arbitrary change in the index, I have to set that flag. Trivial, perhaps (obviously in this example), but to me it seems like a harbinger of unreadable, bug-friendly code.
What's the best way, without using a second variable, to test if a value's changed over time?
If your answer is, "there isn't one, just be quiet and use a flag variable", then I congratulate you for promoting bad code design. /s
1Yeah, I know it's not technically operator overloading; have you a better, more quickly understandable term?
You can use another magic method to intercept assignment of the attribute. It's called __setattr__(). Here is an example of how to use it:
In [2]: class Test(object):
def __setattr__(self, name, value):
print(name, "changed to", value)
super().__setattr__(name, value)
...:
In [3]: t = Test()
In [4]: t.name = 4
name changed to 4
In [5]: t.name = 5
name changed to 5
I have a dictionary, named
descendDict
And it contains 4 keys which are class objects, which have values that are both letters and other class objects.
Now what I'm trying to do is sort through the dictionary, and call out different actions if the value brought up in the dictionary is a class object, or if it is a letter:
for x in descendDict:
print x, descendDict[x]
for y in descendDict[x][0]:
if y != (classObject?):
#Action
for x in descendDict:
for z in descendDict[x][0]:
if z != (classObject?):
if y == z:
dist = 0
else:
dist = float(nodeDict[y]) + float(nodeDict[z])
In the if statements:
if... != (classObject?):
I am trying to determine whether the variable in the dictionary is, or is not a class object, but i just dont know how to do this.
Here is one the entries:
<__main__.Node instance at 0xb6738> ([<__main__.Node instance at 0xb6710>, 'A', <__main__.Node instance at 0xb6760>], '0.1')
I am sorting through it's first keys list, but i am trying to figure out if the values in the list are a class object, or a letter.
Not sure what you mean by "class object" since everything in Python is a first-class object. If you're trying to figure out if it's an instance of a specific class you can just use isinstance
if isinstance(y, someClass):
# do stuff
its better to define a method in your class then say
if hasattr(d[x],myClassMethodName):#then do this
else:#not a member
this method of checking allows much greater flexibility
for #RussellBorogove
try:
d[x].myMethod(*args,**kwargs)
except:
print "This is not an instance of my class and maybe a letter"
You probably want isinstance(x,type):
x = str
isinstance(x, type)
#=> True
class x(object):pass
isinstance(x, type)
#=> True
class x:pass
isinstance(x, type)
#=> False
x = "foo"
isinstance(x, type)
#=> False
Obviously, you'll have to stick to new-style classes, but you should be anyway.
However, it sounds like you're somehow trying to create your own object dispatch system. I strongly recommend that you move to some kind of common base class for all of your objects, and use method dispatch combined with higher-order methods to achieve whatever you're trying to do.
In Python it's common to use the "easier to ask forgiveness than permission" (EAFP) model, which looks like:
for y in collection:
try:
# treat it like it's a Node
y.actionMethod()
except AttributeError:
# that method doesn't exist, so it's not a Node
# do something else with it
print y
This is preferred over using isinstance(), because it allows you to define several otherwise unrelated classes each with their own actionMethod() without having to change this dispatch code.
Python 2.5.4. Fairly new to Python, brand new to decorators as of last night. If I have a class with multiple boolean attributes:
class Foo(object):
_bool1 = True
_bool2 = True
_bool3 = True
#et cetera
def __init__():
self._bool1 = True
self._bool2 = False
self._bool3 = True
#et cetera
Is there a way to use a single decorator to check that any setting of any of the boolean attributes must be a boolean, and to return the boolean value for any requested one of these variables?
In other words, as opposed to something like this for each attribute?
def bool1():
def get_boo1():
return self._bool1
def set_bool1(self,value):
if value <> True and value <> False:
print "bool1 not a boolean value. exiting"
exit()
self._bool1=value
return locals()
bool1 = property(**bool1())
#same thing for bool2, bool3, etc...
I have tried to write it as something like this:
def stuff(obj):
def boolx():
def fget(self):
return obj
def fset(self, value):
if value <> True and value <> False:
print "Non-bool value" #name of object???
exit()
obj = value
return locals()
return property(**boolx())
bool1 = stuff(_bool1)
bool2 = stuff(_bool2)
bool3 = stuff(_bool3)
which gives me:
File "C:/PQL/PythonCode_TestCode/Tutorials/Decorators.py", line 28, in stuff
return property(**boolx())
TypeError: 'obj' is an invalid keyword argument for this function
Any pointers on how to do this correctly?
Thanks,
Paul
You can try using a descriptor:
class BooleanDescriptor(object):
def __init__(self, attr):
self.attr = attr
def __get__(self, instance, owner):
return getattr(instance, self.attr)
def __set__(self, instance, value):
if value in (True, False):
return setattr(instance, self.attr, value)
else:
raise TypeError
class Foo(object):
_bar = False
bar = BooleanDescriptor('_bar')
EDIT:
As S.Lott mentioned, python favors Duck Typing over type checking.
Two important things.
First, "class-level" attributes are shared by all instances of the class. Like static in Java. It's not clear from your question if you're really talking about class-level attributes.
Generally, most OO programming is done with instance variables, like this.
class Foo(object):
def __init__():
self._bool1 = True
self._bool2 = False
self._bool3 = True
#et cetera
Second point. We don't waste a lot of time validating the types of arguments.
If a mysterious "someone" provides wrong type data, our class will crash and that's pretty much the best possible outcome.
Fussing around with type and domain validation is a lot of work to make your class crash in a different place. Ultimately, the exception (TypeError) is the same, so the extra checking turns out to have little practical value.
Indeed, extra domain checking can (and often does) backfire when someone creates an alternate implementation of bool and your class rejects this perfectly valid class that has all the same features as built-in bool.
Do not conflate human-input range checking with Python type checking. Human input (or stuff you read from files or URI's) must be range checked, but not not type checked. The piece of the application that does the reading of the external data defines the type. No need to check the type. There won't be any mysteries.
The "what if I use the wrong type and my program appears to work but didn't" scenario doesn't actually make any sense. First, find two types that have the same behavior right down the line but produce slightly different results. The only example is int vs. float, and the only time is really matters is around division, and that's taken care of by the two division operators.
If you "accidentally" use a string where a number was required, your program will die. Reliably. Consistently.
This question already has answers here:
How can I represent an 'Enum' in Python?
(43 answers)
Closed 4 years ago.
I've been using a small class to emulate Enums in some Python projects. Is there a better way or does this make the most sense for some situations?
Class code here:
class Enum(object):
'''Simple Enum Class
Example Usage:
>>> codes = Enum('FOO BAR BAZ') # codes.BAZ will be 2 and so on ...'''
def __init__(self, names):
for number, name in enumerate(names.split()):
setattr(self, name, number)
Enums have been proposed for inclusion into the language before, but were rejected (see http://www.python.org/dev/peps/pep-0354/), though there are existing packages you could use instead of writing your own implementation:
enum: http://pypi.python.org/pypi/enum
SymbolType (not quite the same as enums, but still useful): http://pypi.python.org/pypi/SymbolType
Or just do a search
The most common enum case is enumerated values that are part of a State or Strategy design pattern. The enums are specific states or specific optional strategies to be used. In this case, they're almost always part and parcel of some class definition
class DoTheNeedful( object ):
ONE_CHOICE = 1
ANOTHER_CHOICE = 2
YET_ANOTHER = 99
def __init__( self, aSelection ):
assert aSelection in ( self.ONE_CHOICE, self.ANOTHER_CHOICE, self.YET_ANOTHER )
self.selection= aSelection
Then, in a client of this class.
dtn = DoTheNeeful( DoTheNeeful.ONE_CHOICE )
There's a lot of good discussion here.
What I see more often is this, in top-level module context:
FOO_BAR = 'FOO_BAR'
FOO_BAZ = 'FOO_BAZ'
FOO_QUX = 'FOO_QUX'
...and later...
if something is FOO_BAR: pass # do something here
elif something is FOO_BAZ: pass # do something else
elif something is FOO_QUX: pass # do something else
else: raise Exception('Invalid value for something')
Note that the use of is rather than == is taking a risk here -- it assumes that folks are using your_module.FOO_BAR rather than the string 'FOO_BAR' (which will normally be interned such that is will match, but that certainly can't be counted on), and so may not be appropriate depending on context.
One advantage of doing it this way is that by looking anywhere a reference to that string is being stored, it's immediately obvious where it came from; FOO_BAZ is much less ambiguous than 2.
Besides that, the other thing that offends my Pythonic sensibilities re the class you propose is the use of split(). Why not just pass in a tuple, list or other enumerable to start with?
The builtin way to do enums is:
(FOO, BAR, BAZ) = range(3)
which works fine for small sets, but has some drawbacks:
you need to count the number of elements by hand
you can't skip values
if you add one name, you also need to update the range number
For a complete enum implementation in python, see:
http://code.activestate.com/recipes/67107/
I started with something that looks a lot like S.Lott's answer but I only overloaded 'str' and 'eq' (instead of the whole object class) so I could print and compare the enum's value.
class enumSeason():
Spring = 0
Summer = 1
Fall = 2
Winter = 3
def __init__(self, Type):
self.value = Type
def __str__(self):
if self.value == enumSeason.Spring:
return 'Spring'
if self.value == enumSeason.Summer:
return 'Summer'
if self.value == enumSeason.Fall:
return 'Fall'
if self.value == enumSeason.Winter:
return 'Winter'
def __eq__(self,y):
return self.value==y.value
Print(x) will yield the name instead of the value and two values holding Spring will be equal to one another.
>>> x = enumSeason(enumSeason.Spring)
>>> print(x)
Spring
>>> y = enumSeason(enumSeason.Spring)
>>> x == y
True