2013-08-30 9 views
9

ただ、Pythonのdictについて "関数"を考えて、dictが実際には関数ではないことに気付いていました。たとえば、dir(dict)を実行すると、ユーザー定義関数の通常の名前空間には含まれていないすべてのメソッドが取得されます。その考え方を拡張すると、dir(list)dir(len)に似ています。それらは機能していませんが、実際にはtypeです。しかし、私は明らかに機能を述べているドキュメントのページhttp://docs.python.org/2/library/functions.htmlについて混乱しています。 (私はそれが本当に単に組み込み呼び出し可能と言うべきだと思います)Pythonの組み込み関数は実際には関数ではありません。

だから何が得られますか? (クラスと関数の区別をするのは簡単ではないように見える)

+7

[関数のように見え、関数のように振る舞う場合は関数です] (http://stackoverflow.com/a/4205163/489590)、そうですか? –

+1

'dir()'は、利用可能な関数の完全な概要を与えることは決して意図されていなかったことに注意してください。 'dir(type)'はあなたに多くの同じ機能を与えます。 –

+0

私は、これらの点が機能よりもクラスの方向にあることには同意します。結局のところ、 'dict'が純粋な関数であれば動作しないisinstance(x、dict)のようなことができます。 – Alfe

答えて

3

一つの方法は、両方ともcallableであり、両方が(いずれにせよ、CPythonの中で)Cで実装されているもののことで、dicttypeあります。つまり、isinstance(dict, type) == Trueです。これは、あなたが書くことができ、他のタイプの基本クラスとしてdictを使用できることを意味します

class MyDictSubclass(dict): 
    pass 

なく

class MySumSubclass(sum): 
    pass 

これは、ほとんどの組み込みオブジェクトのように動作するクラスを作成することが有用であることができ、しかしいくつかの機能拡張があります。

class Vector(tuple): 
    def __add__(self, other): 
     return Vector(x + y for x, y in zip(self, other)) 

別の興味深いポイントが表示されます:たとえば、あなたの代わりに連結のベクトル加算として+実装tupleのサブクラスを定義することができます。 typeもC言語で実装されています。呼び出し可能です。 dictsumとは異なります)のように、それはtypeのインスタンスです。 isinstance(type, type) == True。この奇妙な、一見不可能なサイクルのために、typeは、新しいクラスのクラス(メタクラスと呼ばれる)の作成に使用できます。 Pythonの3で、

class MyTypeSubclass(type): 
    pass 

class MyClass(object): 
    __metaclass__ = MyTypeSubclass 

のか:あなたは書くことができ、興味深い結果isinstance(MyClass, MyTypeSubclass) == Trueそれを与える

class MyClass(metaclass=MyTypeSubclass): 
    pass 

を。しかし、これがどのように役立つかは、この答えの範囲をはるかに超えています。コンストラクタdict.__init__

dir(dict.__init__) 

dirを呼び出す

5

一般的なクラスと同様に呼び出し可能です。 dict()を呼び出すと、効果的にdictコンストラクタを呼び出すことができます。独自のクラス(C、say)を定義し、C()を呼び出してインスタンス化する場合と似ています。

+2

私は呼び出し可能ですが、なぜドキュメンテーションページで '関数 'と呼んでいるのですか? 'class'と' function'という名前を持つことはとても簡単です。 –

+1

@PhillipCloud私はこの違いを理解していますが、ユーザー定義関数に 'func_closure '、' func_code '、' func_defaults '、' func_dict '、' func_doc 'があるとき、ドキュメントページに組み込み関数があると誤解を招くことはあるでしょうか、 、 'func_globals'、 'func_name'、そして組み込み関数はありません。 –

+0

@EdgarAroutiounianコンストラクタは実際には 'type'オブジェクトのメソッドです。もちろん、このメソッドは特別な種類の関数です。 'def'文で作成された関数(メソッドではない)とクラスとそのコンストラクタを区別することは間違いありません。この区別が簡単ではないと思われるという事実は、多くの関数やクラスを記述していない可能性があることを意味します。クラスと関数の違いや、クラスが呼び出し可能関数にどのように関連しているのか分かっていれば、 'dict'関数を呼び出すのは混乱しているとは思えません。 –

1

dict()は、dictインスタンスのコンストラクタです。 dir(dict)を実行すると、クラスdictの属性が表示されます。 a = dict()と書くときはaをタイプdictの新しいインスタンスに設定します。

ここでは、dict()が「dict関数」と呼ばれていると仮定しています。または、インデックス付きのインスタンスdictを呼び出していますか? a['my_key']関数? dictsum、たとえば、と比較して、特別であること

+0

はい、 'dict()'関数を参照してください。 –

+0

私は 'dict()'コンストラクタを初期化関数以上のものにしているので、それを 'dict()'コンストラクタと呼ぶ方が良いと思います。また、新しいインスタンスを割り当てます。 –

+0

@ Code CodeMonkey '' dict() ''をコンストラクタと呼ぶことの願いが、あなたが確かに知っている他の言語の影響を受けないのだろうか?私はこの願いに同意しない。ドキュメントのインデックスを見ると、 '' constructor''というエントリは ''オブジェクト.__ init __(self [、...]) ''につながります。複雑なものは、複雑さを増すことなく、既に1つの単語に自己定義を与えることで十分です。 – eyquem

0

注意はあなたが他の機能のために取得したいのと同じものを含め、期待する何を与えます。 dict()コンストラクタを呼び出すと、dict.__init__(instance)が呼び出されるため、これらの関数の属性がどこにあるかが説明されます。 (もちろん、任意のコンストラクターで少し余分なバックグラウンドの作業がありますが、これはオブジェクトの場合と同様にdictsでも同じです)

関連する問題