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にバインドされたものに名前をバインドするだけです。次に、あなたはやっています:RSARSA

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()が実際に 2 つのオブジェクトを作成していることがわかりますが、これらはもちろん同一ではありません。これは、次を使用して実証されているように、最初の例とは対照的です。

>>> class RSA:
...   def __init__(self):
...     print("foo")
... 
>>> obj = RSA()
foo
>>> obj is obj
True
于 2012-11-20T17:16:37.480 に答える
1

ええと...それclass RSAもインスタンスであるため、変数に格納できます(これは2番目のメソッドが行っていることです)が、実際には両方で同じことをしているわけではないことを指摘する必要があります。あなたがするとき:

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

実際には RSA のコンストラクターを 2 回呼び出しているため (呼び出しが 2 回あります)、コンソールにobj()2 つの " 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()

グローバルとローカルGettattr と setattr ( 12 )

そして、もう少し掘り下げたい場合は...メタクラスでできるクレイジーなこと...(StackOverflowでこれまでに見た中で最高の回答の1つで説明されています)

于 2012-11-20T17:30:12.633 に答える
1

の後obj = RSA、 と の両方が同じクラスRSAを参照します - ただし、 のインスタンスを作成していません。このことを考慮:objRSA

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

Bar = Foo

Foo()
Bar()

出力:

フー
フー

どちらの方法がより好ましいかという点では、実際に何をしようとしているのかによって異なります。ただし、一般的には、2 番目の方法を使用する正当な理由がない限り、最初の方法を使用することをお勧めします。

于 2012-11-20T17:14:46.947 に答える