【问题标题】:Object Attribute in Random List Not Accessible in PythonPython 中无法访问随机列表中的对象属性
【发布时间】:2009-07-01 00:57:37
【问题描述】:

我正在开发我的第一个面向对象的 python 位,我有以下内容:

#!/usr/bin/python 
import random 

class triangle:

# Angle A To Angle C Connects Side F
# Angle C to Angle B Connects Side D
# Angle B to Angle A Connects Side E

    def __init__(self, a, b, c, d, e, f):
        self.a = a
        self.b = b
        self.c = c
        self.d = d
        self.e = e
        self.f = f

    #def solver:
        #pass

#initialize Triangle
myTri = triangle(0,0,0,0,0,0)

#Pick Three Random Angles or Sides to Generate Values For
sample = random.sample([myTri.a, myTri.b, myTri.c, myTri.d, myTri.e, myTri.f],  3)

#Sets the three randomly picked variables to a Random Number



sample[0] = random.randint(1, 100)
sample[1] = random.randint(1, 100)
sample[2] = random.randint(1, 100)

我如何传递 myTri.a,例如传递给 random.randint。它正在传递它初始化的“0”的值。我希望能够为 myTri 的三个 .a-.f 属性分配一个随机值。我错过了什么?

【问题讨论】:

  • 我假设您将检查随机分配给属性是否会产生有效的三角形。您的三角形过于指定;您只需要 3 个属性(例如,每边的长度,或 2 个长度和包含的角度),其他 3 个属性是派生的。在为属性分配随机值之前,也许您需要考虑一下。约定是称你的类为三角形,而不是三角形。类没有“初始化”;您正在做的是创建一个(无效!)三角形实例并将其命名为“myTri”。呃,请阅读 PEP8。 HTH。
  • 感谢您的意见。 1. 我已更改三角形以匹配 PEP8。我已经用谷歌搜索了这个并添加了书签。我将在未来使用它来阐明应该如何设置样式。 2. 我不明白你说的无效是什么意思。你的意思是数学上还是python上无效?我正在检查以确保 ABC(三个角度)不超过 180。 3. 不确定“也许你需要考虑这个……”是什么意思,因为我不确定“这个”是什么意思是。这里的想法是,如果提供足够的信息,程序将能够解决缺失的角度/边。
  • 数学上有效。 3 个角度之和必须正好是 180 度。这给你留下了一个可变的边长和两个可导出的边长。 “this”是确保有效性的练习。如果你得到 3 个神奇地加到 180 的角,边都将为零;您建议如何解决缺少的 3 个方面??
  • 我认为这是随机分配给仅 3 个属性的关键。如果你得到 SAS 或 SSS,你可以为其他人解决,如果你得到 ASS 或 AAA,你就不能,你会显示一些东西......
  • 约翰库格曼你是对的。这基本上是为了确定关于给定三角形的所有已知信息,只知道三个属性。

标签: python random object oop


【解决方案1】:

当你说[myTri.a, myTri.b, ...] 时,你并没有得到变量本身的列表,或者对它们的引用。相反,你得到的只是他们的价值观。既然你知道它们被初始化为0,就好像你写了[0, 0, 0, 0, 0, 0]。没有区别。

然后当您尝试分配给sample[0] 时,实际上您只是用随机值覆盖了存储在该数组中的 0。那时,Python 对myTri 一无所知。连接丢失。

您可以执行以下操作来获得您想要的效果。首先,将我们稍后要分配的变量名称列表传递给random.sample

sample = random.sample(["a", "b", "c", "d", "e", "f"], 3)

这将返回 3 个随机变量名称。现在我们要分配给具有相同名称的变量。我们可以通过使用特殊的setattr 函数来做到这一点,该函数接受一个对象和一个变量名并设置其值。例如,setattr(myTri, "b", 72)myTri.b = 72 做同样的事情。所以重写我们有:

setattr(myTri, sample[0], random.randint(1, 100))
setattr(myTri, sample[1], random.randint(1, 100))
setattr(myTri, sample[2], random.randint(1, 100))

这里的主要概念是您正在进行一些反思,也称为内省。你有动态变量名——你不确切知道你在惹谁——所以你必须咨询一些更奇特的、不碍事的语言结构。通常情况下,我实际上会提防这种愚蠢的做法,但这是一个罕见的例子,内省是一个合理的解决方案。

【讨论】:

    【解决方案2】:

    分配给abc

    myTri.a = random.randint(1, 100)
    myTri.b = random.randint(1, 100)
    myTri.c = random.randint(1, 100)
    

    a-f分配给一个随机属性:

    attrs = ['a', 'b', 'c', 'd', 'e', 'f']
    setattr(myTri, random.choice(attrs), random.randint(1, 100))
    

    a-f分配给三个随机属性:

    attrs = ['a', 'b', 'c', 'd', 'e', 'f']
    for attr in random.sample(attrs, 3):
      setattr(myTri, attr, random.randint(1, 100))
    

    【讨论】:

    • 这可行,但不适用于我的应用程序,因为我不想只设置前三个。
    • 由于某种原因我不能。现在有道理了!与之前的海报相比,有什么理由这样做吗?
    • 以前的?我的先发布了 1 分钟。 :P 我们都有相同的答案,使用 setattr(),差异是肤浅的。
    • 好吧,我以为它们是肤浅的,但我现在已经到了真正想学习 python 并真正了解发生了什么而不是破解它的地步。对不起,你是对的,你快了 1 分钟!
    【解决方案3】:

    使用 setattr 的替代方法:在创建 Triangle 实例时使用。

    args = [random.randint(1, 100) for i in xrange(3)] + [0, 0, 0]
    random.shuffle(args)
    my_tri = Triangle(*args)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-05
      • 1970-01-01
      相关资源
      最近更新 更多