PyObjectに関する質問への回答

みなさんこんにちは。 この記事では、pyobject.ruサイトからPythonに関する質問とタスクに回答し、これを行った理由を説明します。 質問自体はこちらから入手できます



免責事項

すぐに警告します:投稿はpythonとプログラミング全般でnoobで書かれています。 明確化やコメントがあれば(そして、そうすることを望みます)、書いてください。




回答は質問と同じカテゴリに分類されます。

PS Pythonバージョン2.6.6があります



それでは始めましょう。



データ型、基本構造



便宜上、小さなテストクラスを作成します。

class Foo(object): """docstring for Foo""" arg1 = None _arg2 = None __arg3 = None def __init__(self): super(Foo, self).__init__() def bar(self): pass
      
      







1.オブジェクトのすべての属性のリストを取得する方法

  print dir(Foo)
      
      







2.オブジェクトのすべてのパブリック属性のリストを取得する方法

Pythonでは、保護属性を示すために「_」が使用され、プライベートでは、変数名の前に「__」が使用されます。 したがって、パブリック属性のみのリストを取得するには、すべての属性のリストをフィルタリングする必要があります。 これは、リスト式の助けを借りて行うことができます(リスト内包表記):

  print [arg for arg in dir(Foo) if not arg.startswith('_')]
      
      





または、フィルター機能を使用します。

  print filter(lambda x: not x.startswith('_'), dir(Foo))
      
      





私の場合、最初のオプションの方が読みやすいので望ましいです。



3.オブジェクトメソッドのリストを取得する方法

Pythonの関数とメソッドは第1種のオブジェクト(正しく記述されているのですか?)であるため、getattr関数を使用して、オブジェクト自体の属性を返すgetattr関数と、チェックを実行する呼び出し可能関数を使用します。

  print [arg for arg in dir(Foo) if callable(getattr(Foo, arg))] #  print filter(lambda arg: callable(getattr(Foo, arg)), dir(Foo))
      
      







4.ヘルプの内容はどの「魔法」変数に保存されますか?

__doc__属性内。 この変数には、直後にコメントが入力されます

クラス/メソッド/関数の宣言(テストクラスを参照)。



  print Foo.__doc__
      
      





ヘルプ機能をインタラクティブに使用することもできます。

  >>> help(int)
      
      







5. 2つのタプルがあり、3番目を最初の2つの連結として取得します

  print (2, 5) + (4, 6)
      
      







6. 2つのタプルがあり、最初の2つのタプルの一意の要素の結合として3番目を取得します。

この課題では、2つのアプローチを見ました。

1.タプル内の要素をチェックするループを作成します

2.ビルトインセットタイプ(本質的にハッシュ)を使用します。これには論理操作を適用できます。

2番目のアプローチを使用したソリューション(XORを使用):

  print tuple(set((2, 3, 4)) ^ set((4, 5)))
      
      







7.ループ内でリストが変更された場合、なぜfor x in lst [:]が使用されますか。これは[:]を意味しますか?

[:]-Pythonでのカットの指定。 それらについては、たとえばここで読むことができます 。 要するに:[:]はlstのコピーを作成し、最初の変更は元の値の反復に影響しません。



8. 1つのキーと他の値に同じ長さの2つのリストがあります。 辞書を作ります。

値のペアのタプルを作成するzip関数と、渡された引数の辞書を作成するdictを使用します。

  a = ('John', 'Peter') b = (1, 2) print dict(zip(a, b))
      
      







9. 1つのキーと他の値に、長さが異なる2つのリストがあります。 辞書を作ります。 値がないキーの場合、値としてNoneを使用します。 無視するキーがない値。

  a = ('John', 'Peter', 'Daniel') b = (1, 2) print dict((len(a) > len(b)) and map(None, a, b) or zip(a, b)) #    if/else,   Python 2.5 print dict(map(None, a, b) if (len(a) > len(b)) else zip(a, b))
      
      





この場合、zip、ma​​p関数を使用します。 zipの特徴は、返される結果が反復可能な最短のものに制限されることです。 つまり、キーよりも値の方が多い場合に最適です。 2番目のpythonブランチでは、mapに1つのドキュメント化された機能があります。つまり、反復可能な値のいずれかが他の値より短い場合、Noneが追加されます。 関数の代わりにNoneが渡されると、ユニオンが実行され、出力で同じタプルが取得されます。

または、2.6で追加されたitertools.izip_longest関数の使用を検討してください。



10.辞書があります。 それを反転します。 つまり ペアキー:値のスワップ-値:キー。

  a = {'John': 1, 'Peter': 2} print dict((val, key) for (key, val) in a.iteritems())
      
      





または、zip関数を再度使用します。

  a = {'John': 1, 'Peter': 2} print dict(zip(a.itervalues(), a.iterkeys()))
      
      





PSこの場合に使用するのに適切なもの-zipまたはitertools.izip-を指導者に提案してください。 値/ itervalueについても同じことが言えます。



11. Unicodeには文字列があり、utf-8およびcp1251でエンコードされた8ビット文字列を取得します

記事を書いた時点で書きましたが、タスクを正しく理解できていれば、

  greeting = u'' print greeting.encode('utf-8') print greeting.encode('cp1251')
      
      







12. cp1251エンコードされた文字列があり、ユニコード文字列を取得します

同様に:

  greeting = '' print greeting.decode('cp1251')
      
      







機能



1.引数をリスト/タプルとして、または一度に1つずつ渡すことができる関数を作成します。 関数はすべての引数を合計します。

解決策は次のように見えます:転送されたリストに対する反復。 リスト項目に__len__属性がある場合、つまり反復可能であれば、それを展開して関数に渡します。

  def sum(*args): """ Returns sum of the args. >>> sum(1) 1 >>> sum(2, 2) 4 >>> sum(1, 2, (3, 4)) 10 >>> sum(1, ()) 1 >>> sum(-1, 1.0) 0.0 """ result = 0 for arg in args: if hasattr(arg, '__len__'): result += sum(*arg) else: result += arg return result
      
      







2.引数付きの追加関数を返すファクトリ関数を作成します。

関数は第1種のオブジェクトなので(混乱させるほど大きい場合)、それらを使用するためのオプションの1つは、他の関数またはメソッドから関数を返し、引数として渡すことです。 一番下の行は、引数の1つである加算関数を返す必要があるということです

これは作成時に設定され、2つ目は異なる場合があります。 私が理解しているように、これはクロージャーです-関数本体の外部で宣言された変数へのアクセス。

  def addition_inner(val): """ >>> add5 = addition_inner(5) >>> add5(3) 8 >>> add1 = addition_inner(-1) >>> add1(3) 2 >>> add_str = addition_inner('s') >>> add_str(3) Traceback (most recent call last): ... TypeError: unsupported operand type(s) for +: 'int' and 'str' """ def func(arg): return arg + val return func def addition_lambda(val): """ >>> add5 = addition_lambda(5) >>> add5(3) 8 >>> add1 = addition_lambda(-1) >>> add1(3) 2 >>> add_str = addition_lambda('s') >>> add_str(3) Traceback (most recent call last): ... TypeError: unsupported operand type(s) for +: 'int' and 'str' """ return lambda x: x + val
      
      







3.アイテム2に似たファクトリを作成しますが、そのような関数のリストを返します

この場合、上で書いた関数のリストを返すことは理にかなっています。

次のようになります。

  def additions(start, end): """ Returns list of addition functions >>> for addition in additions(0, 5): ... print addition(1) 1 2 3 4 5 >>> print additions(5, 0) [] >>> print additions(0, 2) # doctest: +ELLIPSIS [<function func at 0x...>, <function func at 0x...>] """ return [addition_inner(val) for val in range(start, end)]
      
      





4.アナログマップを作成します。

-最初の引数は、関数または関数のリストです

-2番目の引数-関数に渡される引数のリスト

-これらの関数は単一の引数の関数であると考えられています

組み込みマップを使用してこのタスクを実装しました(オプションとして-ループに置き換えられました)。 また、渡された値の型を確認するために、hasattrおよび__len__ magicメソッドの類似物として、isinstance関数とcollectionsモジュールを使用しました。

  def mymap(func, args): """ Applies list of functions for args. >>> add0 = addition_inner(0) >>> add1 = addition_inner(1) >>> add2 = addition_inner(2) >>> add5 = addition_inner(5) >>> print mymap(add5, [1, 2, 3]) [6, 7, 8] >>> print mymap([add0, add1, add2], [1, 2, 3]) [(1, 2, 3), (2, 3, 4), (3, 4, 5)] >>> print mymap([], []) [] >>> print mymap(sum, [(3, 4, 5, 6, (7,))]) [25] """ if isinstance(func, collections.Iterable): return [tuple(map(f, args)) for f in func] #  #return [tuple(f(arg) for arg in args) for f in func] else: return [func(arg) for arg in args]
      
      







イテレータ



少し余談。 イテレータコードを書くことにはあまり意味がありませんでした。 それらのコードはitertoolsモジュールのドキュメントに記載されています。 書くのは難しいでしょう。

イテレーターはジェネレーターに基づいており、優れた記事があります。



モジュール



1.インポートされたモジュールfooがあります。ファイルの物理パスを見つける方法、どこから来たのですか?

パスは__file__モジュール属性に保存されます。



2. fooモジュールから、feedparserモジュールをインポートします。 feedparserのXバージョンはサイトパッケージのシステム全体のディレクトリにあり、バージョンYはfooモジュールの横にあります。 環境変数PYTHONPATHが定義されており、feedparserバージョンZもあります。どのバージョンが使用されますか?

バージョンYがインポートされます。

ドキュメント(チュートリアルのセクション6)によると、インポート順序は次のとおりです。

1.実行されたスクリプトの隣のディレクトリ

2. PYTHONPATH

3.システムカタログ



3. Pythonがモジュールを検索するディレクトリのリストを見る方法は?

  >>> import sys >>> sys.path
      
      







4. fooモジュールがあり、その中にbarモジュールがインポートされます。 fooモジュールの隣には、bar.pyおよびbar / __ init__.pyファイルがあります。

2番目のものが使用されます。 パッケージ。 私が理解しているように、ディレクトリは再帰的に走査され、パッケージが最初にインポートされます。



5. __name__ == '__main__'コンストラクトの意味とその理由

ファイルがインポートまたは起動されたかどうかを判断するために使用されます。 実行すると値は__main__になり、インポートすると値はモジュールの名前になります。



今日はすべてです、ありがとう。

PS誰もが興味を持っている場合-私は最後の2つのセクションに答えの私のバージョンを書きます。



All Articles