3

このコードがあります:

def f():
  pass

print("f: ", dir(f))
print("len: ", dir(len))

出力:

f:  ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
len:  ['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

f関数と関数lenの属性が異なるのはなぜですか? 組み込み関数であることは知っていlenますが、それでも同じ属性を持たないのはなぜですか?

4

1 に答える 1

9

C 定義関数は異なる型であり、ユーザー定義関数のみが特定の機能 (属性の追加、関数定義のネスト、スコープ名の参照など) をサポートするためです。

ユーザー定義関数が提供する追加の属性を見てみましょう。

>>> sorted(set(dir(f)) - set(dir(len)))
['__annotations__', '__closure__', '__code__', '__defaults__', '__dict__', '__get__', '__globals__', '__kwdefaults__']

たとえば、C 定義の関数には、クロージャーやグローバルはなく、バイトコードもありません。それぞれを分析する:

  • __annotations__: 関数定義に追加された注釈。これは Python 構文機能であるため、ユーザー定義関数でのみ実行できます。
  • __closure__: スコープ クロージャから取得されたセルのリスト。C 定義の関数は別の関数内で定義できないため、それらのクロージャーはありません。
  • __code__: Python バイトコード オブジェクト。C 定義関数にはそれがありません。
  • __defaults__: C で定義された関数にはデフォルト値 (キーワード) がある場合がありますが、それらはイントロスペクトできる Python 値として定義されていません。
  • __dict__: C 定義関数には任意の属性を設定できませんが、ユーザー定義関数には設定できます。
  • __get__: これにより、ユーザー定義関数が記述子になり、クラス内のメソッドとして機能します。ほとんどの C 関数はこれを必要としません。
  • __globals__: ユーザー定義関数はモジュールで定義されます。これは、グローバル名前空間を指します。C 定義の関数には、指す Python モジュールの名前空間がありません。
  • __kwdefaults__: 同様です__defaults__が、キーワードのみのパラメーターの場合は、dict として; 繰り返しますが、Python 関数だけがこれらを持つことができます。
于 2013-05-28T18:18:39.217 に答える