2

我有一些课:

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++ 的方式思考,但无论如何,令我惊讶的是它也可以工作!
这里到底发生了什么?哪种方式更受欢迎?这对我来说有些神秘。

提前感谢您的任何回复!

4

3 回答 3

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
于 2012-11-20T17:16:37.480 回答
1

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

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

Bar = Foo

Foo()
Bar()

输出:

富
富

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

于 2012-11-20T17:14:46.947 回答
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 和 Locals Gettattr 和 setattr ( 12 )

如果你想深入挖掘......你可以用元类做的疯狂的事情......(在我在 StackOverflow 中见过的最好的答案之一中解释过)

于 2012-11-20T17:30:12.633 回答