3

I just want to achieve some extra which is not there in operator module of python like not_contain. For that I created my own class with the not_contain method. I just want to do some more variation and for that I need the class. I am using python3.

class UserDefinedOperators:
    def not_contain(self, a, b):
            return a not in b
    def some_other_function(self, a, b):
            some other work here

Now I am creating an Enum like this

import operator
import enum

class MyOperators(enum.Enum):
    LT = operator.gt
    GT = operator.gt
    NOT_CONTAIN = UserDefinedOperators().not_contain

I am having following differences in accessing the Enum value

>>> MyOperators
<enum 'MyOperators'>
>>> MyOperators.LT
<MyOperators.LT: <built-in function gt>>
>>> MyOperators.LT.value
<built-in function gt>
>>> MyOperators.LT.name
'LT'
>>> MyOperators.NOT_CONTAIN
<bound method UserDefinedOperators.not_contain of <__main__.UserDefinedOperators object at 0x100cdbeb0>>
>>> MyOperators.NOT_CONTAIN.value
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'value'
>>> MyOperators.NOT_CONTAIN.name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'name'
>>> 

So with the class function, the Enum shows

AttributeError: 'function' object has no attribute 'value'

I read on other SO answer that it is getting assigned as function and not Enum attributes that is why it doesn't have .value or .name attributes. But then built in operator.lt and operator.gt is also a function then how come it is working fine and have .value and .name properties?

The error does come with normal function not just class function but I want to understand what difference it is in operator module? How can I achieve the same with my class?

1 Answer 1

1

Enum uses the presence of the __dunder__ method __get__ to determine if an object is a function/class. Functions and classes created in Python all have a __get__ method, but built-in functions do not.

To get around this problem you can use the aenum1 module and its member function:

from aenum import Enum, member
import operator

class UserDefinedOperators:
    #
    @staticmethod
    def not_contain(self, a, b):
            return a not in b


class MyOperators(Enum):
    LT = operator.lt
    GT = operator.gt
    NOT_CONTAIN = member(UserDefinedOperators.not_contain)

and in use

>>> list(MyOperators)
[
  <MyOperators.LT: <built-in function lt>>,
  <MyOperators.GT: <built-in function gt>>,
  <MyOperators.NOT_CONTAIN: <function UserDefinedOperators.not_contain at 0x7f9c875ed790>>,
  ]

Note that I made not_contain be a staticmethod. This is appropriate since the not_contain method does not require any instance nor class data to do its job. This also means you do not need to instantiate UserDefinedOperators with creating the NOT_CONTAIN enum member.


1 Disclosure: I am the author of the Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) library.

Sign up to request clarification or add additional context in comments.

1 Comment

I'll point out, too, that a class of nothing but static methods is just a dressed-up dictionary with functions for values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.