Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我应该如何在这个类中的函数之间传递变量?_Python_Python 3.x_Class_Oop_Decomposition - Fatal编程技术网

Python 我应该如何在这个类中的函数之间传递变量?

Python 我应该如何在这个类中的函数之间传递变量?,python,python-3.x,class,oop,decomposition,Python,Python 3.x,Class,Oop,Decomposition,我想做的是: 执行脚本时,我必须输入两个数字,然后它会比较它们。 我想被问三次。 第一次我将输入10和5,第二次输入5和10,第三次我将输入10和10,以得到所有三个可能的答案 第一个代码的问题是:getnumbers()正在Checknumbers()的内部调用。 我想要创建函数和循环,并且严格地只在专用循环中执行函数,而不是在另一个函数中执行 我希望一切都清晰明了,在另一个函数中没有任何函数的引用,我也不想使用任何全局变量 我用一门课解决了这个问题,但我不确定我是在破坏语言,还是这是一种常见

我想做的是: 执行脚本时,我必须输入两个数字,然后它会比较它们。 我想被问三次。 第一次我将输入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
  • 我认为第一个解决方案没有任何错误(除了在Python 3中
    getumbers
    返回字符串这一事实)。类并不是解决所有问题的方法

  • 我不能在我的函数中引用任何其他函数,如何在不引用它们的情况下传递x和y

    传递某个内容时不引用它是不可能的。即使
    x
    y
    是全局变量(这比您当前的设计糟糕得多),使用函数也需要引用它们


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

如果您不想在
checknumbers()
中调用
getnumbers()
,唯一有意义的选择就是将数字作为参数传递给
checknumbers()

这至少有更好的关注点分离。

  • 在类和实例之间,以及在类属性和实例属性之间,您会感到困惑。(例如阅读)
    • 存储状态变量(如x,y)以便不必在函数(/method)调用之间传递它们的OO方法是使它们成为实例属性。(不是像您所做的那样使用类属性。别担心,我第一次学习Python时也是这样做的)
    • 因此,我们声明一个类
      UI
      ;我们将在其方法中访问其实例属性,如
      self.x,self.y
    • 不要试图直接在类UI上进行操作。您必须首先实例化它:
      ui=ui()
      。您应该遵循Python约定,即类名为大写/CamelCase:
      UI
      ,实例名为小写,例如
      UI、ui1、ui2…
    • 您试图将代码直接放入UI的类定义中,而不是定义方法并将代码放入其中,而您的UI类甚至没有
      \uuuu init\uuuu()
    • 方法是类中的函数,它们总是有第一个参数
      self
      。如果没有,该方法将无法访问类的其余部分(!)
  • 现在我们已经澄清了这一点,有两种方法可以分解方法来完成您想要做的事情:
  • 有一个空的
    \uuuu init\uuuu()
    (您可以让它的主体执行
    传递
    )。让
    get_numbers()
    check_numbers()
    成为单独的方法,您可以按顺序手动调用这些方法。这是我在下面展示的内容,与您所说的最接近(“我不希望引用其他函数中的任何函数”),但分解不好-如果客户端在
    获取数字()之前调用
    检查数字()
    ,该怎么办?由于
    \uuuu init\uuuu()
    初始化x,y时不使用任何值,因此它会在TypeError上爆炸
  • 最好让
    \uuu init\uuu()
    在引擎盖下调用方法
    get\u numbers()
    ,以确保实例正确初始化。(如果我们想输入新的数字,我们可以在以后再次调用
    get_numbers()
    )。这很容易改变,我把它留给你
  • 在方法1中,我们必须将实例成员初始化为某个对象(否则在
    check_numbers()
    中尝试访问它们会爆炸)。因此,我们初始化为
    None
    ,如果我们比较,它会故意抛出异常。其实这并不重要,这只是糟糕的分解,没有正确地初始化实例(并调用完成该操作所需的任何方法)。这就是方法2的原因。这样更好。通常,您应该始终拥有一个将类初始化为已知状态的
    \uuuu init\uuu()
    ,以便可以安全地调用任何其他方法
代码:

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

  • 简单计数器不需要while循环:
    n=0
    while(n<3)
    <代码>n+=1
。for循环是一个单行程序:
用于范围(3)中的n:
  • 好的Python风格(参见PEP-8)是用下划线命名方法小写,因此
    get\u numbers(),check\u numbers()
  • 设计类的一个很好的自上而下的方法是首先编写它的方法签名,考虑需要什么方法和属性,以及它们如何协同工作。例如:“
    get_numbers()
    将获取用户输入,因此我们需要属性
    self.x,y
    来存储数字,以便
    检查数字()
    可以访问它们”。这样,在编写代码墙之前,您就应该解决类设计中的任何问题

  • 将其作为参数传递不起作用:回溯(最后一次调用):File“/Users/bla/Documents/Python/test4.py”,第23行,在checknumbers()类型错误:checknumbers()中缺少2个必需的位置参数:“x”和“y”@Barry传递参数如果操作正确,则会起作用。错误消息表示您仍在尝试调用函数作为
    checknumb
    
    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
    
    def getnumbers():
        x = input("Enter the X number: ")
        y = input("Enter the Y number: ")
        return x, y
    
    def checknumbers():
        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):
        getnumbers()
        checknumbers()
        n += 1
    
    def getnumbers():
        x = int(input("Enter the X number: "))
        y = int(input("Enter the Y number: "))
        return x,y
    
    def checknumbers(x, y):
        if x > y:
            # etc.
    
    ...
    
    for _ in range(3):
        x,y = getnumbers()
        checknumbers(x,y)
    
    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()