【问题标题】:When defining a python class, how to set a random variable in it?定义一个python类时,如何在里面设置一个随机变量?
【发布时间】:2017-05-16 12:30:03
【问题描述】:

假设我有一个名为Person 的课程,其中只有人的姓名和性别。

性别应从男性和女性中随机选择。为此,我导入了 random.randint() 函数。随机性别是根据随机int确定的。

import random

class Person:
    alias = random.randint(1, 3)
    if alias == 2:
        gender = 'Male'
    else:
        gender = 'Female'

    def __init__(self, name):
        self.name = name

r = Person('rachel')
s = Person('Stanky')
print(r.gender)
print(s.gender)

但是,我从这个班级的不同人得到的结果都是相同的性别。我的理解是randint 一旦生成就固定了。我的问题是如何使每个类实例都不同。

【问题讨论】:

  • 类顶层的代码只运行一次(在导入时)。如果您想为每个实例做出选择,请将代码放在 __init__ 方法中。

标签: python class random


【解决方案1】:

你永远不会得到不同性别的原因是因为性别属性是一个 class 变量。一旦 Python 创建了你的类对象 Persongender 的值就不再计算了。您需要将gender 变量设为instance 属性。这意味着性别将基于每个实例而不是每个类定义来计算。例如:

import random

class Person:
  def __init__(self, name):
      self.name = name
      alias= random.randint(1, 3)
      if alias == 2:
          self.gender = 'Male'
      else:
          self.gender = 'Female'

r= Person('rachel')
s= Person('Stanky')

print(r.gender) 
print(s.gender)

哪些输出

Female
Male

附带说明,我认为您的任务更好的选择是使用random.choice() 从性别列表(男性或女性)中选择随机性别:

from random import choice

class Person:
  genders = ('Male', 'Female', 'Female')
  def __init__(self, name):
      self.name = name
      self.gender = choice(Person.genders)

rachel = Person('Rachel')
stanky = Person('Stanky')

print(rachel.gender) 
print(stanky.gender)

请注意,在我上面的示例中,Person.genders 一个类变量。这是故意的。因为我们只需要一次创建一个性别列表,我们可以让这个列表成为一个类级别的变量。

【讨论】:

  • 另一件值得一提的事情:使用self.gender = random.choice(['Male', 'Female']) 可以简化很多。
  • @Mac 我正要添加一个编辑说完全相同的事情。伟大的思想活着,是吗? ;-)
  • 您应该明确地将choice 方法放在顶部。这才是解决问题的正确方法!
  • @MSeifert 虽然我非常同意,但在我看来,最好先回答 OP 的 original 问题(参见meta discussion for more info)。但是你说得对,我会添加一条评论,说使用 choice 方法是更好的方法。
  • 你是对的。也可能意味着女性与男性的比例为 2:1(randint 包括端点)。在这种情况下,choice 方法需要是 choice(['male', 'female', 'female'])... 最好将 randint 放在顶部,只要没有明确说明意图。
【解决方案2】:

看来你已经猜对了为什么性别没有改变的原因。要解决此问题,您可以使用 property 代替 gender

import random

class Person(object):
    def __init__(self, name):
        self.name = name

    @property
    def gender(self):
        try:
            # If it has been defined for the instance, simply return the gender
            return self._gender
        except AttributeError:
            # If it's not defined yet, define it, and then return it
            self._gender = random.choice(['male', 'female'])
            return self._gender

r = Person('rachel')
s = Person('Stanky')
print(r.gender)
print(s.gender)

【讨论】:

  • 这与 :def __init__(self, name): self.name = name self.gender = random.choice(['Male','Female']) 有什么不同吗?因为我在这里看到的是如果没有声明性别变量,那么我们声明一个新的性别变量。但是,这个类只有一个变量,即名称。这意味着肯定不会定义任何性别局部变量,不是吗?
  • 你是对的,它是不同的。只要您不访问属性gender_gender 变量就未定义。但是,一旦您访问该属性,它将被定义。所以这是一个不同的实现,但在大多数情况下,它的行为与__init__ 解决方案完全相同。
【解决方案3】:

您应该将随机性别生成放在__init__ 下,以便为每个类实例随机生成。

import random

class Person:
    def __init__(self, name):
        self.name = name
        alias= random.randint(1, 3)
        if alias == 2:
            self.gender = 'Male'
        else:
            self.gender = 'Female'

r= Person('rachel')
s= Person('Stanky')
print(r.gender)
print(s.gender)

三倍的结果:

$ python classRandom.py 
Male
Female
$ python classRandom.py 
Female
Female
$ python classRandom.py 
Female
Male

【讨论】:

    【解决方案4】:

    gender 变量目前是一个类变量,这就是为什么它对于所有创建的实例都保持不变。您需要将它们更改为实例的属性。

    旁注:random.randint(1, 3) 将返回 1、2 或 3 而不仅仅是 1 或 2。它与索引不同,后者忽略结尾。现在,成为女性的机会更高,因为它可能是 1 或 3,所以random.randint(1,2) 更有意义。我提到了这一点,以防万一它不是故意的。您也可以使用random.choice,它将从列表中随机选择。

    import random
    
    class Person:
    
        def __init__(self, name):
            self.name = name
            self.gender= random.choice(["Male", "Female"]) # or random.choice(["Male", "Female", "Female"]) if you want a higher chance of being a female
    
    r= Person('rachel')
    s= Person('Stanky')
    print(r.gender)
    print(s.gender)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      • 2021-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多