我创建了这样的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'>
我也尝试过使用lambda,但它看起来不太好,虽然它有效:
Gender.RANDOM()
是否有其他方法可以每次获取随机值,而不使用lambda表达式?
我们使用这个枚举对象作为某个方法的参数的默认值,这个方法应该是属性而不是函数,因为当我们使用Gender.FEMALE
时它不是函数,它& #39;是一个属性,Gender.RANDOM
也应该是一个属性:
def full_name(gender=Gender.FEMALE):
...
def full_name(gender=Gender.RANDOM):
...
答案 0 :(得分:11)
正如其他人所说,最好的方法是让random()
成为枚举类中的一种方法,以明确RANDOM
不是成员。
然而,因为我喜欢谜题:
from enum import Enum
import random
class enumproperty(object):
"like property, but on an enum class"
def __init__(self, fget):
self.fget = fget
def __get__(self, instance, ownerclass=None):
if ownerclass is None:
ownerclass = instance.__class__
return self.fget(ownerclass)
def __set__(self, instance, value):
raise AttributeError("can't set pseudo-member %r" % self.name)
def __delete__(self, instance):
raise AttributeError("can't delete pseudo-member %r" % self.name)
class Gender(Enum):
FEMALE = 'female'
MALE = 'male'
@enumproperty
def RANDOM(cls):
return random.choice(list(cls.__members__.values()))
将此作为函数定义中的默认值将无法满足您的需求。这种标准方法是:
def full_name(gender=None):
if gender is None:
gender = Gender.RANDOM
这对读者来说会让人感到困惑。使用常规方法会更好:
def full_name(gender=None):
if gender is None:
gender = Gender.random()
答案 1 :(得分:5)
我尝试了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
的对象,因此RANDOM
具有property def full_name(gender=Gender.RANDOM):
...
。
但是,您在问题中描述的以下代码无法按预期方式运行。
RANDOM
def full_name(gender=None):
gender = gender or Gender.RANDOM
...
属性只会被调用一次。要知道原因,请阅读answer。默认参数类似于函数的属性,它只会被初始化一次。
为此我建议你做这样的事情:
data() {
return {
...
req: {},
...
}
}
答案 2 :(得分:3)
您可能应该在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()
答案 3 :(得分:2)
我认为你想要一个方法随机,而不是直接将值保存在变量中,因为如果这样做,值将永远不会改变:
如果你想要一个功能
随机导入 import enum
class Gender(enum.Enum):
MALE = 'male'
FEMALE = 'female'
RANDOM = random.choice([MALE, FEMALE])
def __getattribute__(self,item):
if item == "RANDOM":
Gender.RANDOM = random.choice([self.MALE, self.FEMALE])
return Gender.RANDOM
else:
return object.__getattribute__(self, item)
gender = Gender()
外观:
gender.RANDOM
=> 'female'
gender.RANDOM
=> 'male'
gender.RANDOM
=> 'male'
gender.RANDOM
=> 'male'
gender.RANDOM
=> 'female'
gender.RANDOM
=> 'male'
gender.RANDOM
=> 'male'
gender.RANDOM
=> 'female'
答案 4 :(得分:2)
由于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()
# ...
答案 5 :(得分:0)
来自文档:“枚举是一组符合唯一,常量值的符号名称(成员)。” 你需要切换到另一个类似的表示。
答案 6 :(得分:0)
虽然在很多情况下修改课程可能会更清晰,但是如果您只是这样做一次或者不想修改枚举,您可以这样做:
random.choice([enm.value for enm in Gender])
答案 7 :(得分:0)
另一个适用于您的目标的选项是:
from enum import Enum
import random
class Gender(Enum):
MALE = object()
FEMALE = object()
@classmethod
def get_random_gender(cls):
gender = random.choice(cls._member_names_)
return gender.lower()
print(Gender.get_random_gender())
>> female