【问题标题】:Is there a Python equivalent to the grave accent in bash scripting?是否有与 bash 脚本中的重音等效的 Python?
【发布时间】:2011-11-19 06:01:15
【问题描述】:

我不喜欢使用大量的 IF 语句。在不得不使用大量 IF 语句来完成它的世界中,这就是我现在正在玩的东西:

首先,一些变量...

pick_level = 1
lockpicking_level1_maxxp = 40
lockpicking_level2_maxxp = 70
lockpicking_level3_maxxp = 100

现在我们要开锁了。 A successful pick happens when a random number between 1 and anything up to the current lockpicking skill level's max xp divided by 2 is chosen.所以对于级别 1,它是介于 1 和 20 之间的任何值 - 级别 2,介于 1 和 35 之间的任何值,而级别 3 是介于 1 和 50 之间的任何值。下面是 IF 语句的样子:

x = random.randint(1, 100)
if pick_level == 1:
  if x not in range(1, (lockpicking_level1_maxxp / 2)):
    print 'You failed to pick the lock'
    ...
elif pick_level == 2:
  if x not in range(1, (lockpicking_level2_maxxp / 2)):
    etcetc

我想做的是根据 pick_level 的值确定 xp,而不必做一堆 IF 语句一遍又一遍地询问相同的问题。它会像这样(使用 bash 中的重音):

if x not in range(1, (lockpicking_level`pick_level`_maxxp / 2)):

通过这种方式,我可以根据 pick_level 的值让代码自动变为“lockpicking_level1_maxxp”、“lockpicking_level2_maxxp”或“lockpicking_level3_maxxp”,从而避免所有 IF 语句。

虽然我已经有一段时间没有编写 bash 脚本了,所以我对它的工作原理的记忆可能有点模糊。我也知道 `` 在 Python 版本 3 之前与使用 repr() 基本相同,所以这不是如何做到的。有什么办法可以做到这一点,还是我一直在写丑陋的 IF 语句?

我想我可以像这样使用字典:

lockpicking_maxxp = {1:20, 2:35, 3:50}
...
if x in range(1, lockpicking_maxxp[pick_level]):

...但我不知道这是否正是我设置技能数据库的方式(尽管它可能最终会成为 JSON 文件。我喜欢 JSON。)

非常感谢您的宝贵时间。我期待更多地了解这个想法。

【问题讨论】:

  • 使用字典。任何相当于使用 eval 的东西都是丑陋的,容易给出无用的错误,更难理解,最糟糕的是完全没有必要。
  • 尝试阅读面向对象的编程。从长远来看,它将使处理更复杂的事情变得更加容易。 Shell/Bash 脚本只有原始数据结构,python 装备更好,dict 和 set 让生活变得更好。 eval() 和朋友在 shellscripts 中是可以的,但在干净的高级语言中,它被认为是不好的风格。但是不要让这阻止你,无论你怎么做,编程都是非常有趣的! :D

标签: python bash variables dynamic replace


【解决方案1】:

Don't repeat yourself。尽可能使用数据结构而不是单个对象:

lockpicking_maxxp = {
    1: 40,
    2: 70,
    3: 100
}

x = random.randint(1, 100)
if x > lockpicking_maxxp[pick_level] / 2:
    print 'You failed to pick the lock'
    ...

当然,你可能在这个游戏中有其他技能,所以你可能想要更多类似的东西:

maxxp = {
    'lockpicking': {
        1: 40,
        2: 70,
        3: 100
    }, 'trap_searching': {
        1: 50,
        ...
    }, ...
}

skill = 'lockpicking'
x = random.randint(1, 100)
if x > maxxp[skill][level[skill]] / 2:
    print 'You failed to pick the lock'
    ...

【讨论】:

  • 你是对的。归根结底,当我超越对单个原型的破解时,将需要一个实际的数据结构来保存所有内容。我想我会做一个名为技能的默认字典,然后我可以按照你的建议做,就像如果 x 不在范围内(1,技能 ['lockpicking'][pick_level]):从技术上讲,我想声明这个答案,因为它是适合这种情况的编码技术,但我认为正式我应该将 Avaris 的答案标记为“已接受”,因为他们以一种将值动态插入变量名称的方式进行了回复:P
【解决方案2】:

您可以使用locals() 将本地符号表作为dict 获取并使用它来获取变量值。即:

>>> pick_level = 1
>>> lockpicking_level1_maxxp = 40
>>> lockpicking_level2_maxxp = 70
>>> lockpicking_level3_maxxp = 100
>>> locals()["lockpicking_level%d_maxxp" % pick_level]
40

【讨论】:

  • 同意。我个人不会这样设计我的代码,但 this 正是他所要求的,不是吗?
  • 确实,就我的“是否可以将值动态插入变量名称”的问题而言,这似乎是这样做的方法。如前所述,我会更好地使用字典,特别是因为我将拥有的不仅仅是这项技能。但是很好地找到了这个问题的答案,它已经在我的脑海里萦绕了一段时间,今天它的用途出现了,所以我想我会一劳永逸地弄清楚它:D
【解决方案3】:

每当您觉得需要向变量添加数字时,您可能应该只使用一个列表:

pick_level = 1
lockpicking_levels = [0,40, 70, 100]

test = random.randint(1, 100)

if test < lockpicking_levels[pick_level] / 2:
    print "you failed"
else:
    ...

【讨论】:

  • 感谢您的回复!事实上,使用数据结构来保存值似乎会更好,这样我就可以只引用那一件事。它不仅减少了 IF 语句,而且还减少了变量混乱!
猜你喜欢
  • 1970-01-01
  • 2013-02-04
  • 2012-11-21
  • 2012-04-10
  • 2019-03-23
  • 1970-01-01
  • 2012-08-26
  • 1970-01-01
  • 2013-06-07
相关资源
最近更新 更多