python使用不同的方法调用类的方法

时间:2012-11-20 17:09:36

标签: python oop class object

我有一些课程:

class RSA:
 CONST_MOD=2
 def __init__(self):
  print "created"

 def fast_powering(self,number,power,mod):
  print "powering"

我想实例化它并调用方法fast_powering:

 def main():
  obj=RSA() # here instant of class is created 
  val=obj.fast_powering(10,2,obj.CONST_MOD)  #  and we call method of object
  print val

它工作正常!

但我发现我可以做一点点不同的方式,比如:

def main():
 obj=RSA #do we create a link to the class without creating of object , or what?
 val=obj().fast_powering(10,2,obj().CONST_MOD) # and here we do something like
          # calling of static method of class in C++ without class instantiation,
          #  or ?
 print val

抱歉,我认为有点用C ++方式,但无论如何 令我惊讶的是它也有效!
这里到底发生了什么?哪种方式更优惠?这对我来说有些神秘。

提前感谢您的回复!

3 个答案:

答案 0 :(得分:3)

在你的例子中,你正在做:

obj = RSA

只是将名称obj绑定到绑定到RSA的任何内容,这是您实例中的类RSA。然后你正在做:

obj().fast_powering(…)

这相当于创建RSA的实例并在其上调用方法fast_powering。请注意,这样,您将在每次调用时获得RSA的新实例,这可能不是您想要的。您还会注意到,__init__方法已在上面引用的行中调用过。还要考虑:

>>> class RSA:
...   def __init__(self):
...     print("foo")
... 
>>> obj = RSA
>>> obj() is obj()
foo
foo
False

在这里,我们看到语句obj() is obj()实际上创建了两个对象,这些对象当然不相同。这与您的第一个示例相反,如使用:

所示
>>> class RSA:
...   def __init__(self):
...     print("foo")
... 
>>> obj = RSA()
foo
>>> obj is obj
True

答案 1 :(得分:1)

obj = RSA之后,RSAobj都引用同一个类 - 您创建RSA的实例,但是。考虑一下:

class Foo:
    def __init__(self):
        print 'Foo'

Bar = Foo

Foo()
Bar()

输出:

Foo
Foo

就哪种方式更为可取:它实际上取决于你想要做什么。但总的来说,第一种方法更可取,除非你有充分的理由使用第二种方法。

答案 2 :(得分:1)

嗯......事实证明class RSA也是一个实例,所以你可以将它存储在变量中(这是你的第二种方法正在做的事情),虽然我需要指出你实际上并没有这样做两者都是一样的。当你这样做时:

val=obj().fast_powering(10,2,obj().CONST_MOD)

你实际上是两次调用RSA的构造函数(你有两个obj()调用),因此你会在控制台上看到两个“ created ”消息。

在Python中做同样的事情有很多奇怪的方法。为了便于阅读,我更喜欢“常规”方式(第一种方法中显示的方式),但这里是合法可行的事情的快速示例:

#!/usr/bin/env python

class RSA(object):
    CONST_MOD=2
    def __init__(self):
        print "created"

    def fast_powering(self,number,power,mod):
        print "powering"

def method1_good():
    obj=RSA() # here instant of class is created 
    val=obj.fast_powering(10,2,obj.CONST_MOD)  #  and we call method of object
    print val

def method2_bad():
    obj=RSA #do we create a link to the class without creating of object , or what?
    val=obj().fast_powering(10,2,obj().CONST_MOD)
    print val

def method3_badToo():
    getattr(RSA(), "fast_powering")(10,2,RSA().CONST_MOD)

def method4_areYouNuts():
    for key, val in globals().iteritems():
        if isinstance(val, type) and (key == "RSA"):
            obj = val()
            getattr(obj, "fast_powering")(10,2,obj.CONST_MOD)
            break

if __name__ == "__main__":
    print "Works with method1?"
    method1_good()
    print "Works with method2?"
    method2_bad()
    print "Works with method3?"
    method3_badToo()
    print "Works with method4?"
    method4_areYouNuts()

也许这可能会给你一些东西要寻找,例如: Globals and Locals Gettattr和setattr(12

如果你想再多挖一点......你可以用metaclasses做的疯狂的事情...(在我在StackOverflow中见过的最好的答案之一中解释)