Могу ли я определить мои переменные * внутри * функции? - PullRequest
0 голосов
/ 29 апреля 2020

Недавно я столкнулся с вопросом новичка во время самообучения, который попросил меня написать программу для расчета заработной платы с учетом входных данных за отработанные часы и почасовую ставку. За любые часы старше 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: [отредактировано]", строка 20 , в p = computepay (h, r) NameError: имя 'h' не определено

Итак, есть ли способ написать computepay, чтобы он самодостаточен таким образом? Я не знаю, почему я чувствую себя обязанным сделать это, но я действительно действительно это делаю.

Ответы [ 3 ]

4 голосов
/ 29 апреля 2020

Да, вы можете. Проблема, как указывает сообщение об ошибке, заключается в том, что h и r не существуют в точке, где вы вызываете функцию:

p = computepay(h,r)

Обратите внимание, что это отличается h и r из тех, что определены внутри функции! Прочтите scopes , если вас это смущает.

Решение состоит в том, чтобы опустить аргументы как в определении функции, так и на сайте вызова:

def computepay():
    ...

p = computepay()

Однако необходимо сделать так, чтобы эти переменные были аргументами. Это делает вашу функцию более универсальной, если она делает одну вещь (вычисление оплаты), а не две ортогональные вещи (запрос ввода, затем вычисление оплаты). Если вы передаете значения в качестве аргументов, функция не заботится о том, откуда они берутся, поэтому вызывающий код может прочитать их из файла или из GUI без необходимости изменения самой функции.

Это универсальность также делает функцию более пригодной для модульного тестирования, которое Python особенно хорошо поддерживает в форме doctests .

Если вы все еще овладеваете основами языка , вы не должны беспокоиться об этом. Я просто подумал, что упомяну это.

1 голос
/ 29 апреля 2020

ИМХО, было бы наиболее целесообразно сохранить функцию computepay такой, какая она есть: принимая некоторые аргументы, вычисляя что-то из этих аргументов, а затем возвращая результат. Затем вы можете поместить весь свой код в функцию, которую я здесь назвал main по соглашению, которая будет вызываться позже:

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

main()
1 голос
/ 29 апреля 2020

Можно указать значения по умолчанию None, чтобы определить, требуется ли ввод пользователя:

def computepay(h<b>=None</b>, r<b>=None</b>):
    <b>if h is None:
        h = input("Enter Hours:")
    if r is None:
        r = input("Enter hourly rate in dollars:")</b>
    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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...