элемент - как получить рандомное число в python




Как получить случайное значение атрибута Enum на каждой итерации? (5)

Вам, вероятно, следует создать метод в вашем Enum для получения случайного пола:

import random
import enum

class Gender(enum.Enum):
    FEMALE = 'female'
    MALE = 'male'

    @classmethod
    def get_gender(cls):
        return random.choice([Gender.FEMALE, Gender.MALE])

Gender.get_gender()

Я создал такой объект Enum :

class Gender(Enum):
    FEMALE = 'female'
    MALE = 'male'
    RANDOM = random.choice([FEMALE, MALE])

и я хочу получить действительно случайное значение каждый раз, но это не работает:

>>> class Gender(Enum):
...    MALE = 'male'
...    FEMALE = 'female'
...    RANDOM = choice([MALE, FEMALE])
... 
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>
>>> Gender.RANDOM
<Gender.MALE: 'male'>

Я также попытался использовать лямбда, но это выглядит не так хорошо, хотя это работает:

Gender.RANDOM()

Есть ли другой способ получить случайные значения каждый раз, без использования лямбда-выражений?

Мы используем этот объект enum как значение по умолчанию для аргумента метода some, поэтому он должен быть атрибутом, а не функцией, потому что когда мы используем Gender.FEMALE это не функция, а атрибут, а Gender.RANDOM должен быть атрибут тоже:

def full_name(gender=Gender.FEMALE):
    ...


def full_name(gender=Gender.RANDOM):
    ...

Из документации: «Перечисление - это набор символических имен (членов), привязанных к уникальным постоянным значениям». Вам нужно переключиться на другое представление, например класс.


Так как RANDOM самом деле не элемент вашего перечисления, я думаю, что более последовательным подходом было бы сохранить его именно как метод, а не атрибут (это не так!).

import random
import enum


class Gender(enum.Enum):
    MALE = 'male'
    FEMALE = 'female'

    @staticmethod
    def random():
        return random.choice(list(Gender))

Затем вы можете перенести поведение «Я не выбираю» в функцию, где это на самом деле имеет больше смысла.

def full_name(gender=None):
    if gender is None:
        gender = Gender.random()
    # ...

Хотя изменение класса может быть более ясным и DRY-er во многих случаях, если вы делаете это только один раз или не хотите изменять перечисление, которое вы можете сделать:

random.choice([enm.value for enm in Gender])


Я пробовал способ с metaclasses . И это работает!

import random
import enum
class RANDOM_ATTR(enum.EnumMeta):
    @property
    def RANDOM(self):
        return random.choice([Gender.MALE, Gender.FEMALE])


class Gender(enum.Enum,metaclass=RANDOM_ATTR): #this syntax works for python3 only
    FEMALE = 'female'
    MALE = 'male'


print(Gender.RANDOM)   #prints male or female randomly

Здесь, делая RANDOM_ATTR метаклассом Gender , Gender похож на объект класса RANDOM_ATTR , поэтому Gender имеет property RANDOM .

Однако приведенный ниже код, который вы описали в своем вопросе, работает не так, как вы ожидаете.

def full_name(gender=Gender.RANDOM):
    ...

Свойство RANDOM будет RANDOM только один раз. Чтобы узнать почему, пожалуйста, прочитайте этот answer . Аргументы по умолчанию подобны атрибутам функции, которые будут инициализированы только один раз.

Для этого я бы предложил вам сделать что-то вроде этого:

def full_name(gender=None):
    gender = gender or Gender.RANDOM
    ...






enums