4

pythonがsorted()に渡されたメソッドをどのように処理するかについて質問があります。次の小さなスクリプトについて考えてみます。

#!/usr/bin/env python3

import random

class SortClass:
    def __init__(self):
        self.x = random.choice(range(10))
        self.y = random.choice(range(10))
    def getX(self):
        return self.x
    def getY(self):
        return self.y

if __name__ == "__main__":
    sortList = [SortClass() for i in range(10)]
    sortedList = sorted(sortList, key = SortClass.getX)
    for object in sortedList:
        print("X:", object.getX(),"Y:",object.getY())

これにより、次のような出力が得られます。

X: 1 Y: 5
X: 1 Y: 6
X: 1 Y: 5
X: 2 Y: 8
X: 2 Y: 1
X: 3 Y: 6
X: 4 Y: 2
X: 5 Y: 4
X: 6 Y: 2
X: 8 Y: 0

このスクリプトは、各インスタンスのxフィールドの値に従ってSortClassオブジェクトを並べ替えます。ただし、ソートされた「key」引数は、SortClassの特定のインスタンスではなく、SortClass.getXを指していることに注意してください。Pythonが「キー」として渡されたメソッドを実際にどのように使用するかについて少し混乱しています。渡されるオブジェクトは「self」引数と同じタイプであるため、このようにgetX()を呼び出すことはできますか?これは「キー」引数の安全な使用法ですか?

4

2 に答える 2

8

クラスのメソッドは単なる関数です。

class MyClass(object):
...     def my_method(self): pass
...
>>> MyClass.my_method
<function my_method at 0x661c38>

クラスのインスタンスからメソッドをフェッチするとき、Python はいくつかの魔法 (記述子と呼ばれる) を使用して、バインドされたメソッドを返します。バインドされたメソッドは、呼び出されたときにインスタンスを最初の引数として自動的に挿入します。

>>> MyClass().my_method
<bound method MyClass.my_method of <__main__.myClass object at 0x6e2498>>

ただし、お気づきのように、最初の引数としてインスタンスを使用して関数を直接呼び出すこともできます。MyClass.my_method(MyClass())

それが で起こっていることsorted()です。Python は、たまたま SortedClass のインスタンスであるリスト内のアイテムを使用して関数 SortedClass.getx を呼び出します。

(ちなみに、あなたがしていることを行うためのより良い方法があります。まず、メソッドを使用して のような属性を公開しないでgetXください。プロパティまたはプレーンな属性を使用してください。また、 と を見てくださいoperator.itemgetteroperator.methodcaller)

于 2009-04-21T02:55:17.103 に答える
0

ベンジャミンの答えに+1。

また、Python での並べ替えをマスターしたい場合は、並べ替えのハウツーをお読みください: http://docs.python.org/howto/sorting.html

于 2011-10-18T17:02:04.903 に答える