6

该程序修改了“myclass”类的对象_x 和_y,但我没有将它作为参数传递给函数try_block。对象如何被修改?

class AddSub:
    def _init_(self): #how do default parameters work? 
        self._x, _y

    def set_x(self, num):
        self._x = num

    def set_y(self, num):
        self._y = num   

    def add(self):
        return self._x + self._y

    def sub(self):
        return self._x - self._y

def try_block():
    try:
        ch = int(input("type 1 to add, and 2 to subtract: "))

        myclass.set_x(int(input("enter an x value: "))) #how does myclass get modifed?

        myclass.set_y(int(input("enter a y value: ")))

        return ch

    except ValueError:
        print("Invalid entry.")

        ch = try_block()

        return ch


myclass = AddSub()

choice = try_block()

if choice == 1:
    print(myclass.add())

elif choice == 2:
    print(myclass.sub())
4

4 回答 4

10

在我回答你的问题之前,我想提一些关于术语的事情。你的myclass价值是一个实例,而不是一个类。您的代码中确实有一个类,名为AddSub. 当您调用时,AddSub()您创建了该类的一个实例。为此类事情学习正确的术语很重要,这样您就可以提出好的问题并理解您得到的答案。

您的代码接近工作,因为您将AddSub类的实例保存到名为myclass. try_block稍后,您从该函数调用该全局变量的一些方法。这在 Python 中是合法的,但通常不推荐。

相反,您应该将对象作为参数传递:

def try_block(value):
    try:
        value.set_x(whatever())
    except ValueError:
        pass

您可以通过将 AddSub 类的实例传递给函数来调用它:

myAddSub = AddSub() # create the instance
try_block(myAddSub) # pass it to the function

这要好得多,因为它不依赖于具有特定值的全局变量来工作AddSub,如果需要,您可以使用许多不同的实例调用它。

当前损坏的代码的一部分是AddSub类的构造函数。无需声明变量。您可以随时分配给他们。如果你想设置默认值,你也可以这样做:

def __init__(self):
    self._x = 0
    self._y = 0

相反,如果您希望能够在构造对象时设置值,则可以向该__init__方法添加其他参数。它们也可以有默认值,允许调用者省略部分或全部:

def __init__(self, x=0, y=0):
    self._x = x
    self._y = y

使用该定义,所有这些都将是构造AddSub实例的有效方法:

a = AddSub()     # gets default 0 value for both _x and _y
b = AddSub(5)    # gets default 0 value for _y
c = AddSub(y=5)  # gets default 0 value for _x
d = AddSub(2, 3) # no defaults!

最后一点,主要与您的主要问题无关:您的try_block函数命名不佳,并且以比必要的更复杂的方式实现。而不是递归,我认为它作为一个循环更有意义,就像在这个伪代码版本中一样:

def exception_prone_task():
    while True: # loops forever, or until a "return" or "break" statement happens
         try:
             result = do_stuff_that_might_raise_an_exception()
             return result # you only get here if no exception happened

         except WhateverExceptions as e:
             report_about_about_the_exceptions(e)
于 2012-11-21T07:29:00.500 回答
3

简短的回答:Python 中的所有内容都是通过引用传递的。(有些人喜欢加上“按参考”)。

更长的答案是您的代码有点混乱。(没问题,可以改进。)

首先,myclass不应该这样调用,因为它不是一个类。它是类的一个实例AddSub——即该类的对象

其次,类不应该被赋予动词的名称。它们应该是名词

每个类方法的第一个参数应该是self(为简单起见)。下一个参数是在创建类时传递的参数(即,当使用类名时,就像调用函数一样)。

每当你想给参数一个默认值时,你只需=value在参数之后写。

作为未来对象一部分的方法定义中的所有内容都必须以self.(简化)为前缀。这样,你__init__应该看起来像:

    def _init_(self, x=1, y=2): #how do default parameters work? 
        self._x = x
        self._y = y

在我看来,对象变量没有必要使用_(下划线)前缀。

于 2012-11-21T07:27:07.227 回答
3

myclass在模块顶层定义,因此可以作为全局变量访问。

于 2012-11-21T07:27:32.147 回答
-3

Python 中的一切都是对象。因此:参考

于 2012-11-21T07:28:41.723 回答