2012-11-21 26 views
3

该程序修改类“myclass”_x和_y,但我不会将它作为参数 传递给函数try_block。它如何被修改?我是Python的新手。Python 3中的类是否通过引用传递?

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()) 
+5

** **为什么在全能飞行面条怪物的名字你使用setter方法?在python中这样做**非常不合适**。使用公共字段,以防万一你需要setter逻辑使用*属性*。 – ThiefMaster

+0

其次。放开那个吸气机的老大哥。不要用Python编写Java代码。除非你证明你需要的不仅仅是一个简单的属性访问,否则不要写getter和setter。 – GSP

+1

@ThiefMaster:我还记得当初是初学者的时候:) – pepr

回答

6

在我回答你的问题之前,我想提一些关于术语的东西。您的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) 
+0

谢谢你,这是一个很大的帮助!仍然得到一些东西 –

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 

在我看来,它时并不需要使用_(下划线)前缀的对象变量。

2

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

-3

Python中的所有东西都是一个对象。因此:参考

+2

那么,其他语言也使用对象。但这并不意味着他们必须使用引用。 (但这不是我投票的人:) – pepr