Python类自变量

Python类自变量,python,class,self,Python,Class,Self,我很久以前就开始学习python类了,在类中使用self.variables时,有一些东西我不理解。我在谷歌上搜索了一下,但找不到答案。我不是程序员,只是python爱好者。 下面是一个简单类的示例,有两种定义方法: 1) 第一种方式: class Testclass: def __init__(self, a,b,c): self.a = a self.b = b self.c = c def firstMethod(self):

我很久以前就开始学习python类了,在类中使用self.variables时,有一些东西我不理解。我在谷歌上搜索了一下,但找不到答案。我不是程序员,只是python爱好者。 下面是一个简单类的示例,有两种定义方法:

1) 第一种方式:

class Testclass:
    def __init__(self, a,b,c):
        self.a = a
        self.b = b
        self.c = c
    def firstMethod(self):
        self.d = self.a + 1
        self.e = self.b + 2
    def secondMethod(self):
        self.f = self.c + 3
    def addMethod(self):
        return self.d + self.e + self.f

myclass = Testclass(10,20,30)
myclass.firstMethod()
myclass.secondMethod()
addition = myclass.addMethod()
2) 第二种方式:

class Testclass:
    def __init__(self, a,b,c):
        self.a = a
        self.b = b
        self.c = c
    def firstMethod(self):
        d = self.a + 1
        e = self.b + 2
        return d,e
    def secondMethod(self):
        f = self.c + 3
        return f
    def addMethod(self, d, e, f):
        return d+e+f

myclass = Testclass(10,20,30)
d, e = myclass.firstMethod()
f= myclass.secondMethod()
addition = myclass.addMethod(d,e,f)
让我困惑的是这两者中哪一个是有效的? 总是将方法中的变量(我们希望稍后使用的变量)定义为self.variables(这将使它们成为类中的全局变量),然后在该类的其他方法中调用它们(这是上层代码中的第一种方法)是否更好? 或者最好不要将方法中的变量定义为self.variables,而是简单地定义为正则变量,然后在方法末尾返回。然后将它们作为参数“重新导入”到另一个方法中(这在上面的代码中是第二种方式)


编辑:为了澄清,我不想在init方法下定义self.d、self.e、self.f或d、e、f变量。我想在一些其他方法中定义它们,如上面的代码中所示。 很抱歉没有提到这一点。

编辑:


如果要在执行
addMethod
后保留对象内部的值,对于exmaple,如果要再次调用
addMethod
。然后使用第一种方法。如果您只想使用类的一些内部值来执行addMethod,请使用第二种方法。

这两种方法都是有效的方法。哪一个是正确的完全取决于情况

例如

  • 在这里,你可以从中“真正”得到a,b,c的值
  • 您想/需要多次使用它们吗
  • 是否希望/需要在类的其他方法中使用它们
  • 这个类代表什么
  • b和c真的是类的“固定”属性吗,还是它们依赖于外部因素
在您在下面评论中给出的示例中:

假设a,b,c依赖于一些外部变量(例如a=d+10,b=e+20,c=f+30,其中d,e,f在实例化类时提供:
myclass=Testclass(“hello”,d,e,f))
。是的,假设我也想在类的其他方法中使用a、b、c(或self.a、self.b、self.c)变量

因此,在这种情况下,“正确”的方法主要取决于您是否期望a、b、c在类实例的生命周期中发生变化。例如,如果您有一个属性(a、b、c)永远不会或很少改变的类,但您大量使用派生属性(d、e、f),那么计算一次并存储它们是有意义的。下面是一个例子:

class Tiger(object):
    def __init__(self, num_stripes):
        self.num_stripes = num_stripes
        self.num_black_stripes = self.get_black_stripes()
        self.num_orange_stripes = self.get_orange_stripes()
    def get_black_stripes(self):
        return self.num_stripes / 2
    def get_orange_stripes(self):
        return self.num_stripes / 2

big_tiger = Tiger(num_stripes=200)
little_tiger = Tiger(num_stripes=30)

# Now we can do logic without having to keep re-calculating values
if big_tiger.num_black_stripes > little_tiger.num_orange_stripes:
    print "Big tiger has more black stripes than little tiger has orange"
这很有效,因为每只老虎都有固定数量的条纹。如果我们将示例更改为使用实例经常更改的类,则out方法也会更改:

class BankAccount(object):
    def __init__(self, customer_name, balance):
        self.customer_name = customer_name
        self.balance = balance
    def get_interest(self):
        return self.balance / 100

my_savings = BankAccount("Tom", 500)
print "I would get %d interest now" % my_savings.get_interest()
# Deposit some money
my_savings.balance += 100
print "I added more money, my interest changed to %d" % my_savings.get_interest()
因此,在这个(有些人为的)例子中,银行账户余额经常变化——因此将利息存储在self.interest变量中没有价值——每次余额变化时,利息金额也会变化。因此,每当我们需要使用它时,计算它是有意义的

为了从这两种方法中获得一些好处,您可以采取许多更复杂的方法。例如,您可以让您的程序“知道”兴趣链接到平衡,然后它将临时记住兴趣值,直到平衡发生变化(这是一种缓存形式-我们使用更多内存,但节省一些CPU/计算)

与原问题无关 关于如何声明类的说明。如果您使用的是Python 2,那么最好让您自己的类继承Python的内置对象类:

class Testclass(object):
    def __init__(self, printHello):
参考号
Python3默认使用这些新样式的类,所以如果使用py3,您不需要显式地从object继承。

如果没有具体而有意义的示例,您真的无法对这类问题得出任何结论,因为这将取决于您试图做什么的事实和环境

话虽如此,在第一个示例中,
firstMethod()
secondMethod()
只是多余的。除了计算
addMethod()
使用的值之外,它们没有任何用途。更糟糕的是,为了实现
addMethod()
函数,用户必须首先对
firstMethod()
secondMethod()
进行两次莫名其妙且显然无关的调用,这无疑是一种糟糕的设计。如果这两种方法真的做了一些有意义的事情,那可能是有意义的(但可能不是),但如果没有一个真正的例子,那就太糟糕了

您可以将第一个示例替换为:

class Testclass:
    def __init__(self, a,b,c):
        self.a = a
        self.b = b
        self.c = c

    def addMethod(self):
        return self.a + self.b + self.c + 6

myclass = Testclass(10,20,30)
addition = myclass.addMethod()
第二个示例类似,除了
firstMethod()
secondMethod()
实际执行一些操作,因为它们返回值。如果出于某种原因,除了将这些值传递给
addMethod()
之外,您希望将这些值分别传递给其他人,那么同样,这可能是有意义的。如果没有,那么您也可以像我刚才那样定义
addMethod()
,并完全省去这两个附加函数,这两个示例之间不会有任何区别

但在缺乏具体例子的情况下,这一切都是非常不令人满意的。现在我们只能说这是一门有点傻的课

通常,OOP意义上的对象是数据(实例变量)和行为(方法)的集合体。如果一个方法不访问实例变量,或者不需要访问实例变量,那么它通常应该是一个独立的函数,而不是在类中。偶尔有一个不访问实例变量的类或静态方法是有意义的,但一般来说,您应该倾向于使用独立函数。

如果您的方法不(或不需要)访问任何实例变量,那么它们根本不需要(也可能不属于)在类中