24

I would like to add a method to my enum.

class Kerneltype(Enum):
    tube = 0
    subspace_KDE = 1
    deltashift = 2
    dist_sens_via_mass_1 = 3

    def aslist(self):
        return [self.tube, self.subspace_KDE, self.deltashift, self.dist_sens_via_mass_1]

    def fromint(self, int):
        return self.aslist()[int]

does not work. Instead of

Kerneltype.aslist()

I currently have to do

[kt[1] for kt in ob.Kerneltype.__members__.items()]
7
  • 9
    "Doesn't work" is a very vague problem description. Please be more specific and provide us with any error messages you're getting. Commented May 23, 2017 at 16:19
  • 5
    Note, your aslist method does not do anything that list(Kerneltype) would not give you automatically. Commented May 23, 2017 at 16:23
  • 1
    The docs can be very helpful here; you don't need a method to iterate over your enum and you can access it by integer index by calling it like a function. Commented May 23, 2017 at 16:31
  • @Ben The function call actually expects a value not index. Commented May 23, 2017 at 16:47
  • 2
    @Ben That's working because the items in the Enum are also similar to indices, change subspace_KDE to say 5 and then try again. Commented May 23, 2017 at 18:18

4 Answers 4

24

You created an instance method, so aslist only exists on instances of Kerneltype (i.e. the enum members themselves). You need a classmethod instead:

@classmethod
def aslist(cls):
    return [cls.tube, cls.subspace_KDE, cls.deltashift, cls.dist_sens_via_mass_1]
>>> Kerneltype.aslist()
[<Kerneltype.tube: 0>, <Kerneltype.subspace_KDE: 1>, <Kerneltype.deltashift: 2>, <Kerneltype.dist_sens_via_mass_1: 3>]
Sign up to request clarification or add additional context in comments.

5 Comments

Why @classmethod and not @staticmethod?
@zzz777 See this question for the difference. Static methods don’t have access to the class type, and as such its class properties.
Sorry could not decipher much from the discussion. I am only using classes because I want to access/manipulate data encapsulated in a class (my past is in c++). The discussion was centered around printing class names in various ways. There are static variables in a class and class variables, is the only big difference is that class variables/methods could be modified by derived classes? It will be really nice if you can shed some light.
@zzz777 Python doesn’t have “static variables” in the sense of other languages. The members in OP’s example, e.g. tube and deltashift, are class variables that are stored on the class/type instead of an instance. If you want to access those, you will need to have a reference to the type. That reference is the cls that is passed to @classmethod methods but not @staticmethod methods.
Sorry it seems like some sort of misunderstanding I am using static variables in classes in python3 right now and it seems working well. Sorry again I will try to formulate my question differently.
6

You should be defining your methods with the classmethod decorator as you are calling them from the class and not the Enum member.

@classmethod
def aslist(cls):
    return [cls.tube, cls.subspace_KDE, cls.deltashift, cls.dist_sens_via_mass_1]

@classmethod
def fromint(cls, int):
    return cls.aslist()[int]

As others have mentioned in comments, your aslist() method is not required and you can directly use list() on it and it by default preserves the order of definition. Only difference is that it doesn't return the aliases.

>>> list(Kerneltype)
[<Kerneltype.tube: 0>, <Kerneltype.subspace_KDE: 1>, <Kerneltype.deltashift: 2>, <Kerneltype.dist_sens_via_mass_1: 3>]

4 Comments

Every member is an instance of the Enum class, and instance methods do make sense (just not in this example).
Fair enough, here's an example: Python Enum, when and where to use?
@EthanFurman Thanks, have updated my answer to remove the bit related to instantiation.
I did a little more rewording -- hopefully you like it. :)
1

You missed the classmethod decorator:

@classmethod
def aslist(self):
    return [self.tube, self.subspace_KDE, self.deltashift, self.dist_sens_via_mass_1]

Comments

-1

The issue with what you do is trying to access enum values via self whereas you should access them as you would normally via the enum.

from enum import Enum

class V(Enum):
    V1 = (1, 2)
    V2 = (2, 3)
    def getKey(v: float):
        return [k for k in list(V) if v > k.value[0] and v < k.value[1]]

V.getKey(1.1) #  [<V.V1: (1, 2)>]
V.getKey(1.1)[0].value # (1, 2) 

Comments

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.