我应该如何在此类的函数之间传递变量?

时间:2018-11-29 12:02:53

标签: python python-3.x class oop decomposition

我正在尝试做的事情: 执行脚本,我将不得不输入两个数字并将其进行比较。 我一共要问3次。 第一次输入10和5,第二次输入5和10,第三次输入10和10,以获得所有三个可能的答案。

我的第一个代码问题是:getnumbers()Checknumbers()内部被调用。 我想创建函数和循环,并且严格只在专用循环内而不是在另一个函数内执行这些功能。

我希望所有内容都清晰易懂,并且不要在另一个函数中引用任何函数,我也不想使用任何全局变量。

我用一堂课解决了这个问题,但是我不确定是要用这种语言还是普遍的做法。另外,我还必须引用checknumbers()函数中的类。

第一个解决方案:

def getnumbers():
    x = input("Enter the X number: ")
    y = input("Enter the Y number: ")
    return x, y

def checknumbers():
    x, y=getnumbers()
    if   x > y:
        print(f'x is larger then y: x is {x} and y is {y}')
    elif y > x:
        print(f"y is larger then x: x is {x} and y is {y}")
    elif y == x:
        print(f"x is equal to y: x is {x} and y is {y}")     
    else:
        print("Dont know mate")


n = 0
while(n < 3):
    checknumbers()
    n += 1

这是该类的变体:

class ui:
    x = input("Enter the X number: ")
    y = input("Enter the Y number: ")


def checknumbers():
    if   ui.x > ui.y:    
        print(f'x is larger then y: x is {ui.x} and y is {ui.y}')
    elif ui.y > ui.x:
        print(f"y is larger then x: x is {ui.x} and y is {ui.y}")
    elif ui.y == ui.x:
        print(f"x is equal to y: x is {ui.x} and y is {ui.y}")     
    else:
        print("Dont know mate")

n = 0
while(n < 3):
    checknumbers()
    n += 1

理想的解决方案,因此两个函数getnumbers()checknumbers都是彼此独立的,并且在while循环内被调用,问题是{{1}中的x和y }函数是getnumbers()所不知道的。

要求是:我无法在函数内部引用任何其他函数,如何在不引用x和y的情况下传递它们?:

checknumbers

3 个答案:

答案 0 :(得分:1)

如果您不想在SELECT * FROM remedi.meds_donation WHERE state_short_name NOT IN ('TN') AND (request_date between "2018-09-01 00:55:48" AND "2018-10-29 13:02:14" or request_date between "2018-09-01 00:55:48" AND "2018-10-29 13:02:14") ORDER BY request_date DESC 中调用getnumbers(),唯一有意义的选择是将数字作为参数传递给checknumbers()

checknumbers()

至少可以更好地分离关注点。

答案 1 :(得分:1)

  • 您会在类和实例之间,类属性与实例属性之间感到困惑。 (例如,阅读this
    • OO状态存储状态变量(如x,y)的方式是使它们成为 instance属性,因此您不必在函数(/方法)调用之间传递它们。 (不是像您正在做的那样的类属性。别担心,当我第一次学习Python时,我也是这样做的。)
    • 因此,我们声明了一个类UI;我们将在其方法内以self.x, self.y的形式访问其实例属性。
    • 不要尝试直接在类UI上进行操作。您必须首先实例化它:ui = UI()。您应该遵循Python约定,即类名是大写/ CamelCase:UI,实例名是小写,例如ui, ui1, ui2...
    • 您试图将代码直接放入UI的类定义中,而不是定义方法并将代码放入其中,并且您的UI类甚至没有__init__()
    • 方法是类内的函数,它们始终具有第一个参数self。如果没有,则该方法将无法访问该类的其余部分(!)
  • 现在我们已经清除了这一点,有两种方法可以分解方法来完成您想做的事情:
    1. 有一个空的__init__()(您可以将其主体设为pass)。将get_numbers()check_numbers()设为单独的方法,您可以按顺序手动调用它们。这是我在下面显示的内容,与您要说的最接近(“我不希望引用另一个函数中的任何函数” ),但是分解不好-如果客户端调用{{1 }}在check_numbers()之前?由于get_numbers()用None初始化x,y,它将在TypeError上爆炸。
    2. 最好是在后台__init__()调用方法__init__()以确保实例正确初始化。 (如果我们想输入新的数字,我们总是可以稍后再致电get_numbers())。这很容易改变,我留给你。
    3. 在方法1中,我们必须将实例成员初始化为 something (否则尝试在get_numbers()中访问它们将失败)。因此,我们初始化为check_numbers(),如果我们进行比较,则将故意抛出异常。没关系,没有None正确初始化实例(并调用完成该过程所需的任何方法)只是不好的分解。这就是方法2更好的原因。通常,您应该始终使用__init__()将类初始化为已知状态,以便可以安全地调用任何其他方法。

代码:

__init__()

此外,还有一些次要的风格要点:

  • 对于简单的计数器,您不需要while循环:class UI: def __init__(self, x=None, y=None): self.x = x self.y = y def get_numbers(self): self.x = input("Enter the X number: ") self.y = input("Enter the Y number: ") def check_numbers(self): """This is bad decomposition because if the client calls check_numbers() before get_numbers(), the NoneType will throw a TypeError""" if self.x > self.y: print(f'x is larger then y: x is {self.x} and y is {self.y}') elif self.y > self.x: print(f'y is larger then x: x is {self.x} and y is {self.y}') elif self.y == self.x: print(f'x is equal to y: x is {self.x} and y is {self.y}') else: print("Don't know mate") # Declare an instance and reuse it three times ui = UI() for n in range(3): ui.get_numbers() ui.check_numbers() n = 0 ... while(n < 3)。 for循环是单线的:n += 1
  • 良好的Python风格(请参阅PEP-8)是将方法命名为lower_case_with_underscores,因此命名为for n in range(3):
  • 一种自上而下的设计类的好方法是先编写其方法签名,考虑所需的方法和属性以及它们如何协同工作。示例:“ get_numbers(), check_numbers()将获得用户输入,因此我们需要属性get_numbers()来存储数字,以便self.x,y可以访问它们”。这样一来,您应该在编写代码墙之前就解决类设计的所有问题。

答案 2 :(得分:0)

  • 第一种解决方案我没有发现任何问题(除了getumbers在Python 3中返回字符串的事实)。类不是解决每个问题的方法

  •   

    我无法在函数内部引用任何其他函数,如何在不引用x和y的情况下传递它们?

    不引用就不可能传递某些东西。即使xy是全局变量(比当前设计差很多),using函数也需要引用它们。

我不明白为什么您会觉得在另一个函数中调用一个函数是错误的或错误的设计。

相关问题