質問

次のように、クラスを初期化せずに呼び出すことができるように、Python で静的メソッドを持つことは可能ですか。

ClassName.StaticMethod ( )
役に立ちましたか?

解決

うん、 staticmethod のデコレータ

class MyClass(object):
    @staticmethod
    def the_static_method(x):
        print x

MyClass.the_static_method(2) # outputs 2

いくつかのコードは、関数ではなく、デコレータとしてstaticmethodを使用して、静的メソッドを定義する古い方法を使用する場合がありますので注意してください。あなたは、Python(2.2および2.3)

の古代のバージョンをサポートしている場合にのみ使用してください
class MyClass(object):
    def the_static_method(x):
        print x
    the_static_method = staticmethod(the_static_method)

MyClass.the_static_method(2) # outputs 2

これは単に

素敵なデコレータ構文を使用していない、(@staticmethodを使用して)第1の実施例と全く同じです

最後に、使用 staticmethod() を控えめに!そこ静的メソッドはPythonで必要な非常に少ない状況があり、私は彼らが別の「トップレベル」の機能が明確にされているだろう、何度も使用さ見てきました。

<時間>

以下は、ドキュメントからの逐語的である:

  

静的メソッドは、暗黙的な最初の引数を受け取りません。静的メソッドを宣言するには、このイディオムを使用します:

class C:
    @staticmethod
    def f(arg1, arg2, ...): ...
     

@staticmethodフォームが関数である デコレータに - <のhref = "https://docs.python.org/2/reference/compound_stmts.html#function" のrel = "noreferrer" タイトルに関数定義の説明を参照してください= "関数の定義"> の関数定義の詳細については、こちらます。

     

これは、(例えばC.f()として)(例えばC().f()など)クラスまたはインスタンスのいずれかで呼び出すことができます。インスタンスは、そのクラスを除いて無視されます。

     

Pythonでの静的メソッドは、JavaやC ++に見られるものと同様です。より高度な概念については、 classmethod() を参照してください。

     

静的メソッドの詳細については、<のhref =「https://docs.python.org/2/reference/datamodel.html#types」のrel =「noreferrer」のタイトルで、標準型の階層にドキュメントを参照してください= "種類"> の標準型の階層のを。

     

新バージョン2.2でます。

     

バージョン2.4で変更:関数デコレータ構文が追加

他のヒント

私はスティーブンは、実際に右のだと思います。元の質問に答えるために、そして、クラスのメソッドを設定するためには、単に最初の引数は呼び出しインスタンスで、その後、あなただけのクラスからメソッドを呼び出していることを確認するつもりはないことを前提としています。

(この答えはあなたがクラス自身のメソッドを呼び出すためのTypeErrorを買ってあげるのPython 2.xではPythonの3.xのことをいう。)

class Dog:
    count = 0 # this is a class variable
    dogs = [] # this is a class variable

    def __init__(self, name):
        self.name = name #self.name is an instance variable
        Dog.count += 1
        Dog.dogs.append(name)

    def bark(self, n): # this is an instance method
        print("{} says: {}".format(self.name, "woof! " * n))

    def rollCall(n): #this is implicitly a class method (see comments below)
        print("There are {} dogs.".format(Dog.count))
        if n >= len(Dog.dogs) or n < 0:
            print("They are:")
            for dog in Dog.dogs:
                print("  {}".format(dog))
        else:
            print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))

fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)

このコードでは、「ROLLCALL」方法は、(それは代わりに、クラスのインスタンスによって呼び出された場合、それはであるように)最初の引数がインスタンスではないことを前提としています。限り「ROLLCALLが」クラスではなくインスタンスから呼び出されるように、コードが正常に動作します。我々は、例えば、インスタンスから「ROLLCALL」を呼び出そう:ます。

rex.rollCall(-1)

しかし、それはそれは二つの引数送りますので、例外を発生させる原因となります。自分自身と-1を、そして「ROLLCALLは」一つだけの引数を受け入れるように定義されている。

なお、rex.rollCall()は、正しい数の引数を送信するだろうが、今関数は、nが数値であることが期待犬のインスタンス(すなわち、レックス)を表すことになるNためにも例外が発生する原因となります。

装飾の出番

これは、次のとおりです。 我々が「ROLLCALL」方法を先行している場合

@staticmethod

、その後、明示的にメソッドが静的であることを示すことによって、私たちも、インスタンスからそれを呼び出すことができます。さて、

rex.rollCall(-1)

に働くだろう。メソッド定義の前に@staticmethodの挿入は、次に、引数として自身を送信インスタンスを停止します。

あなたはコメントアウト@staticmethodラインとない次のコードを試みることによってこれを確認することができます。

class Dog:
    count = 0 # this is a class variable
    dogs = [] # this is a class variable

    def __init__(self, name):
        self.name = name #self.name is an instance variable
        Dog.count += 1
        Dog.dogs.append(name)

    def bark(self, n): # this is an instance method
        print("{} says: {}".format(self.name, "woof! " * n))

    @staticmethod
    def rollCall(n):
        print("There are {} dogs.".format(Dog.count))
        if n >= len(Dog.dogs) or n < 0:
            print("They are:")
            for dog in Dog.dogs:
                print("  {}".format(dog))
        else:
            print("The dog indexed at {} is {}.".format(n, Dog.dogs[n]))


fido = Dog("Fido")
fido.bark(3)
Dog.rollCall(-1)
rex = Dog("Rex")
Dog.rollCall(0)
rex.rollCall(-1)

はい、チェックアウト staticmethod のデコレータます:

>>> class C:
...     @staticmethod
...     def hello():
...             print "Hello World"
...
>>> C.hello()
Hello World

あなたは本当に@staticmethodデコレータを使用する必要はありません。ただ、(自己パラメータを期待していない)と、クラスから呼び出すメソッドを宣言。デコレータはあなたにも(あなたがやりたいことはなかった)。

のインスタンスからそれを呼び出すことができるようにしたい場合にのみ存在しています

主に、あなただけしかし機能を使用して...

  Pythonで

静的メソッド?

     

それは私がそれらを呼び出すことができるようにPythonでの静的メソッドを持つことが可能です   クラスの初期化せずに、同様ます:

ClassName.StaticMethod()
それは Python的<もう少しだが、

はい、静的メソッドは、(次のように作成することができます/>使用する)代わりの方法のためのキャメルケースの下線

class ClassName(object):

    @staticmethod
    def static_method(kwarg1=None):
        '''return a value that is a function of kwarg1'''

上記のデコレータ構文を使用しています。この構文は、

と等価です
class ClassName(object):

    def static_method(kwarg1=None):
        '''return a value that is a function of kwarg1'''

    static_method = staticmethod(static_method)

これは、あなたが述べたと同じように使用することができます:

ClassName.static_method()

静的メソッドの組み込みの例はPythonの2 str.maketrans()モジュール内の関数であったのPython 3にstringされます。

<時間>

あなたはclassmethodで説明するように使用することができます別のオプションは、違いは、クラスメソッドは暗黙の第一引数としてクラスを取得し、サブクラスならば、それは暗黙の第一引数としてサブクラスを取得することです。

class ClassName(object):

    @classmethod
    def class_method(cls, kwarg1=None):
        '''return a value that is a function of the class and kwarg1'''

そのclsは、最初の引数に必要な名前ではなく、最も経験のPythonプログラマーは、あなたが何か他のものを使用している場合、それはひどく行わ検討します注意してください。

これらは通常、代替コンストラクタとして使用されています。

new_instance = ClassName.class_method()

組み込み例はdict.fromkeys()ある

new_dict = dict.fromkeys(['key1', 'key2'])

ほかにどのように静的メソッドオブジェクトの特殊性から、そこに、振る舞うこのそれはあなたのモジュールレベルのコードを整理することになると、あなたがそれらを打つことができる美の一定の一種である。

# garden.py
def trim(a):
    pass

def strip(a):
    pass

def bunch(a, b):
    pass

def _foo(foo):
    pass

class powertools(object):
    """
    Provides much regarded gardening power tools.
    """
    @staticmethod
    def answer_to_the_ultimate_question_of_life_the_universe_and_everything():
        return 42

    @staticmethod
    def random():
        return 13

    @staticmethod
    def promise():
        return True

def _bar(baz, quux):
    pass

class _Dice(object):
    pass

class _6d(_Dice):
    pass

class _12d(_Dice):
    pass

class _Smarter:
    pass

class _MagicalPonies:
    pass

class _Samurai:
    pass

class Foo(_6d, _Samurai):
    pass

class Bar(_12d, _Smarter, _MagicalPonies):
    pass

...

# tests.py
import unittest
import garden

class GardenTests(unittest.TestCase):
    pass

class PowertoolsTests(unittest.TestCase):
    pass

class FooTests(unittest.TestCase):
    pass

class BarTests(unittest.TestCase):
    pass

...

# interactive.py
from garden import trim, bunch, Foo

f = trim(Foo())
bunch(f, Foo())

...

# my_garden.py
import garden
from garden import powertools

class _Cowboy(garden._Samurai):
    def hit():
        return powertools.promise() and powertools.random() or 0

class Foo(_Cowboy, garden.Foo):
    pass

これは、現在、特定の構成要素が使用されることを意図されているコンテキスト内でビットより直感的で、自己文書化となり、個別のテストケースに名前を付けるだけでなく、テストモジュールの下、実際のモジュールにマップする方法に直接的なアプローチを持つため、理想的にはアウトパン純粋主義者のためのテストます。

私は頻繁にそれが実行可能なプロジェクトのユーティリティコードを整理するには、このアプローチを適用するために見つけます。かなり頻繁に、人々はすぐに殺到し、utilsパッケージを作成し、もう1つは120 LOCを持っており、残りはせいぜい2ダースのLOCであるの9つのモジュールで終わります。私はこれで始まり、パッケージに変換し、唯一の真それらに値する獣のためのモジュールを作成することを好むます:

# utils.py
class socket(object):
    @staticmethod
    def check_if_port_available(port):
        pass

    @staticmethod
    def get_free_port(port)
        pass

class image(object):
    @staticmethod
    def to_rgb(image):
        pass

    @staticmethod
    def to_cmyk(image):
        pass

おそらく最も簡単なオプションは、ちょうどクラスの外でこれらの機能を置くことです。

class Dog(object):
    def __init__(self, name):
        self.name = name

    def bark(self):
        if self.name == "Doggy":
            return barking_sound()
        else:
            return "yip yip"

def barking_sound():
    return "woof woof"

この方法を使用して、変更したり(副作用を持っている)内部オブジェクト状態を使用する関数は、クラス内に保持することができ、再利用可能なユーティリティ関数が外側に移動させることができる。

のは、このファイルはdogs.pyと呼ばれているとしましょう。これらを使用するには、dogs.barking_sound()代わりのdogs.Dog.barking_soundを呼び出すと思います。

あなたが本当にクラスの一部であることを静的メソッドが必要な場合は、 staticmethod のデコレータます。

そこで、静的メソッドは、クラスのオブジェクトを作成せずに呼び出すことができる方法です。 例: -

    @staticmethod
    def add(a, b):
        return a + b

b = A.add(12,12)
print b

上記の例では、メソッドaddは、クラス名Aないオブジェクト名によって呼び出されます。

Python の静的メソッドは 2 つの方法で作成できます。

  1. staticmethod() の使用

    class Arithmetic:
        def add(x, y):
            return x + y
    # create add static method
    Arithmetic.add = staticmethod(Arithmetic.add)
    
    print('Result:', Arithmetic.add(15, 10))
    

出力:

結果:25

  1. @staticmethod の使用

    class Arithmetic:
    
    # create add static method
    @staticmethod
    def add(x, y):
        return x + y
    
    print('Result:', Arithmetic.add(15, 10))
    

出力:

結果:25

私は時々この質問に遭遇します。私は好きですユースケースと例があります:

jeffs@jeffs-desktop:/home/jeffs  $ python36
Python 3.6.1 (default, Sep  7 2017, 16:36:03) 
[GCC 6.3.0 20170406] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cmath
>>> print(cmath.sqrt(-4))
2j
>>>
>>> dir(cmath)
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'cos', 'cosh', 'e', 'exp', 'inf', 'infj', 'isclose', 'isfinite', 'isinf', 'isnan', 'log', 'log10', 'nan', 'nanj', 'phase', 'pi', 'polar', 'rect', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau']
>>> 
cmathオブジェクトには状態が存在しないため、

これは、クラスcmathのオブジェクトを作成する意味がありません。しかし、cmathはすべて何らかの形で関係しているメソッドのコレクションです。上記の私の例では、cmath行為の関数のすべての複素数に何らかの方法でます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top