我有一些课程:
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 ++方式,但无论如何
令我惊讶的是它也有效!
这里到底发生了什么?哪种方式更优惠?这对我来说有些神秘。
提前感谢您的回复!
答案 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
之后,RSA
和obj
都引用同一个类 - 您不创建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(1和2)
如果你想再多挖一点......你可以用metaclasses做的疯狂的事情...(在我在StackOverflow中见过的最好的答案之一中解释)