2009-04-21 10 views
4

私はpythonがsorted()に渡されたメソッドをどのように扱うかについて質問します。python3はsorted()の "key"引数に渡されたメソッドで何をしますか?

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オブジェクトを並べ替え:

#!/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()) 

次のような出力が得られます。以下の小さなスクリプトを考えてみましょう。ただし、ソートされた「キー」引数は、SortClassの特定のインスタンスではなく、SortClass.getXを指すことに注意してください。私はちょっと、Pythonが実際に "キー"として渡されたメソッドをどのように使用するかについて混乱しています。渡されたオブジェクトが "self"引数と同じ型であるため、getX()をこのように呼び出すことはできますか?これは「鍵」議論の安全な使用ですか?

+1

注意ゲッターとセッターがunpythonicあること。代わりにoperator.attrgetterを使用して記述してください。ここでの例:http://dpaste.com/hold/36126/ – nosklo

+0

私は 'sortList = [Sortin](範囲内のSortClass())' –

答えて

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>> 

しかし、あなたはまた、直接最初の引数としてインスタンスを持つ関数を呼び出すことができます。sorted()で起こって何MyClass.my_method(MyClass())

を。 PythonはSortedClassのインスタンスであるリスト内の項目を使ってSortedClass.getx関数を呼び出します。

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

関連する問題