【问题标题】:Can I define my variables *inside* a function?我可以在*内部*一个函数中定义我的变量吗?
【发布时间】:2020-04-29 17:45:40
【问题描述】:

最近,我在自学时遇到了一个初学者的问题,该问题要求我编写一个程序来计算给定输入的工作时间和小时费率的工资。对于超过 40 小时的任何时间,都应支付一个半时间。我成功地做到了这一点,但由于某种原因,这对我来说似乎很奇怪。以下代码完美运行,我得到了 100% 的作业:

def computepay(h,r):
    try:
        hrsfloat = float(h)
    except:
        print("Error: 'Hours' must be a number")
        quit()
    try:
        ratefloat = float(r)
    except:
        print("Error: 'hourly rate in dollars' must be a number")
        quit()
    if hrsfloat <= 40:
        return(hrsfloat*ratefloat)
    else:
        x=hrsfloat-40
        return((1.5 * x + 40) * ratefloat)

h = input("Enter Hours:")
r = input("Enter hourly rate in dollars:")
p = computepay(h,r)
print('Pay', p)

但由于某种原因,我宁愿把

 h = input("Enter Hours:")
 r = input("Enter hourly rate in dollars:")

computepay的定义内,采用以下方式:

def computepay(h,r):
    h = input("Enter Hours:")
    r = input("Enter hourly rate in dollars:")
    try:
        hrsfloat = float(h)
    except:
        print("Error: 'Hours' must be a number")
        quit()
    try:
        ratefloat = float(r)
    except:
        print("Error: 'hourly rate in dollars' must be a number")
        quit()
    if hrsfloat <= 40:
        return(hrsfloat*ratefloat)
    else:
        x=hrsfloat-40
        return((1.5 * x + 40) * ratefloat)

p = computepay(h,r)
print('Pay', p)

但这会返回错误:

Traceback(最近一次调用最后一次): 文件“C:[redacted]”,第 20 行,在 p = 计算支付(h,r) NameError: 名称“h”未定义

那么,有没有办法把computepay写成这样自包含呢?我不知道为什么我觉得有必要这样做,但我真的这样做。

【问题讨论】:

  • 如果您要打印p,那肯定是来自某个地方。所以当然,你可以把它放在你的函数中,但是它怎么会回来呢? (您可以将其包含在您的退货中,但这会变得混乱)。因此,实际上您可能想要的是 def printPayFromInput(): ...,它包含您当前在全球范围内拥有的行。这样它仍然很整洁,而且您也不会让computepay 负责做超出它需要做的事情。
  • 这没有什么问题,如果您永远不需要调用compute_pay 来获取从其他地方获取的值。如果您确实从函数内部获取输入,那么compute_pay 没有理由接受任何参数。
  • 简单去掉参数h, r?在函数和对它的调用中。
  • @Mike'Pomax'Kamermans 哦,好主意!谢谢!
  • @chepner,是的,我现在明白了,谢谢!

标签: python function variables


【解决方案1】:

是的,你可以。如错误消息所示,问题在于 hr 在您调用该函数时不存在:

p = computepay(h,r)

请注意,这些 不同 hr 与函数内部定义的那些不同!如果您对此感到困惑,请阅读 scopes

解决方案是从函数定义和调用站点中省略参数:

def computepay():
    ...

p = computepay()

但是,有必要将这些变量作为参数传递。如果它只做一件事(计算工资)而不是两件正交的事情(要求输入,然后计算工资),它会使你的函数更加通用。如果您将值作为参数传递,则函数不会关心它们来自何处,因此调用代码可以从文件或 GUI 中读取它们,而无需修改函数本身。

这种多功能性还使得该函数更适合单元测试,Python 以 doctests 的形式特别支持。

如果您仍在掌握该语言的基础知识,则不必担心这一点。我只是想我会提到它。

【讨论】:

  • 我认为这是我需要的解决方案。该练习指定它应该采用变量,这就是我为什么没有想到这一点的原因。谢谢!
【解决方案2】:

您可以指定None 的默认值以确定是否需要用户输入:

def computepay(h=None, r=None):
    if h is None:
        h = input("Enter Hours:")
    if r is None:
        r = input("Enter hourly rate in dollars:")
    try:
        hrsfloat = float(h)
    except:
        print("Error: 'Hours' must be a number")
        quit()
    try:
        ratefloat = float(r)
    except:
        print("Error: 'hourly rate in dollars' must be a number")
        quit()
    if hrsfloat <= 40:
        return(hrsfloat*ratefloat)
    else:
        x=hrsfloat-40
        return((1.5 * x + 40) * ratefloat)

然后您可以通过几种不同的方式致电computepay,包括

p1 = computepay(40, 19)

p2 = computepay(40)  # Prompts for hours

p3 = computepay(r=19)  # Prompts for hourly rate

p4 = computepay()  # Prompts for hours and hourly rate

【讨论】:

  • 这是一个很好的替代解决方案,特别是因为问题固执地要求我接受变量。谢谢!
【解决方案3】:

恕我直言,保持computepay 函数原样最有意义:获取一些参数,从这些参数中计算一些东西,然后返回结果。然后你可以把你所有的代码放到一个函数中,这里按照惯例我称之为main,稍后会调用它:

def main():
    h = input("Enter Hours:")
    r = input("Enter hourly rate in dollars:")
    p = computepay(h,r)
    print('Pay', p)

main()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-27
    • 2015-01-03
    • 2019-09-29
    • 2020-05-13
    • 1970-01-01
    • 2018-01-28
    • 2017-03-04
    • 1970-01-01
    相关资源
    最近更新 更多