2012-11-20 6 views
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++에서 방법을 생각하지만, 어쨌든 내 큰 놀라움에 너무 작품!
여기 실제로 무슨 일이 일어나고 있습니까? 어느 쪽이 더 좋을까요? 나에게 약간의 신비가있다.

미리 답변 해 주셔서 감사합니다. obj = RSA

답변

3

, 당신은 일을하는지 : 당신의 인스턴스의 클래스 RSARSA에 결합 된 어떤 obj에 이름을 구속력

obj = RSA 

합니다. 그럼 당신은 일을하는지 : RSA의 인스턴스를 생성하고 그것에 방법 fast_powering를 호출하는 것과 같습니다

obj().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 
+0

+1 줄임표 (...)에 오른쪽 그림 문자를 사용합니다. 농담하는 것만으로도 그 해답을 얻으실 수 있습니다. – delnan

1

는 모두 RSAobj는 같은 클래스를 참조하십시오 - 당신은 그러나, RSA의 인스턴스를 생성하지이야. 이것을 고려하십시오 :

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

Bar = Foo 

Foo() 
Bar() 

출력 : 방법이 더 바람직하다 측면에서

 
Foo 
Foo 

: 정말 당신이 뭘 하려는지에 따라 달라집니다. 그러나 일반적으로 두 번째 방법을 사용해야하는 좋은 이유가 없다면 첫 번째 방법이 바람직합니다. 당신의 예에서

+0

링크가 생성 된 경우 Bar = Foo, 클래스 생성 인스턴스입니까? – Tebe

+2

@gekannt 아니요,'Bar'는'Foo' 클래스로 정의되었습니다. 우리가'Bar = Foo'를 할 때'init'이 어떻게 호출되지 않는지 주목하십시오. – arshajii

1

글쎄, 그것은 당신이 (당신의 두 번째 방법이 무엇을하고 있는지되는) 변수에 저장할 수 class RSA이 인스턴스가 너무 밝혀 ... : 사용 입증 된 바와 같이 이것은, 첫 번째 예에 반대한다 내가 지적 할 필요는 있겠지만 실제로 두 사람 모두에서 똑같은 일을하지는 않습니다.당신이 할 경우 :

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

을 당신은 실제로 (두 obj() 통화있어) 두 번 RSA의 생성자를 호출하고, 그래서 당신이 볼이 콘솔에 메시지 "을 만들어".

파이썬에서 똑같은 일을하는 이상한 방법이 있습니다. 가독성을 위해, 나는 "일반적인"방법 (첫 번째 방법에 표시된 하나)을 선호하지만, 여기 법적으로 행할 수있는 것들에 대한 간단한 예입니다 :

#!/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 당신이 ... 당신이 metaclasses로 할 수있는 미친 일을 좀 더 파고하려면 Gettattr 및 않은 setattr (12)

이 그리고 ... (중 하나에서 설명 StackOverflow에서 본 최고의 답변)

+0

두 번째''obj()''호출을 실제로 보지 못합니다 (여러분의 두 번째 단락). –

+0

질문의 세 번째 "코드 블록"(두 번째 main() 예제)에서 복사했습니다. – BorrajaX

+0

아, 저는 인수에서''obj()''를 간과했습니다. –