Pythonでよくわからないオブジェクトに会った時にはdir関数を使おう

この記事は[Takumi Akashiro ひとり Advent Calendar 2020](https://qiita.com/advent-calendar/2020/takumi_akashiro "ひとり Advent Calendar 2020")の13日目の記事です。

限定公開にしてAdventCalendarの時限公開にしてもPV数も伸びないので、

## 始めに

作りたい機能の雑なアタリをつける為に対話型シェルを使う場面って皆様にはありますか？
私はたまにあります。

ただ大体は、よくわからないオブジェクトが返ってきて、コードとかドキュメント見たりするのが面倒だな……
でも中身は何のメソッドやアトリビュートがあるのか解らねえ……って役に立つのが、これ！`dir`関数です

## 使ってみる

早速、使ってみましょう。

```python
>>> dir("Hoge")
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__',
 '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__',
 '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__',
 '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__',
 '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count',
 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha',
 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace',
 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind',
 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip',
 'swapcase', 'title', 'translate', 'upper', 'zfill']
```

はい、マジックメソッドとstr型に実装されているメソッドなどが沢山出てきましたね。

あとはhelp関数と併用すれば、

```python
>>> help("Hoge".join)
Help on built-in function join:

join(iterable, /) method of builtins.str instance
    Concatenate any number of strings.

    The string whose method is called is inserted in between each given string.
    The result is returned as a new string.

    Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'
```

join関数の使い方もよくわかる…って感じです。

なんかよくわからないモジュールに使ってみましょう。

```python
>>> import mmap
>>> dir(mmap)
['ACCESS_COPY', 'ACCESS_DEFAULT', 'ACCESS_READ', 'ACCESS_WRITE', 'ALLOCATIONGRANULARITY',
 'PAGESIZE', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'error', 'mmap']
>>> help(mmap.mmap)
Help on class mmap in module mmap:

class mmap(builtins.object)
 |  Windows: mmap(fileno, length[, tagname[, access[, offset]]])
 |
 |  Maps length bytes from the file specified by the file handle fileno,
 |  and returns a mmap object.  If length is larger than the current size
 |  of the file, the file is extended to contain length bytes.  If length
 |  is 0, the maximum length of the map is the current size of the file,
 |  except that if the file is empty Windows raises an exception (you cannot
 |  create an empty mapping on Windows).
 |
 |  Unix: mmap(fileno, length[, flags[, prot[, access[, offset]]]])
 |
 |  Maps length bytes from the file specified by the file descriptor fileno,
 |  and returns a mmap object.  If length is 0, the maximum length of the map
 |  will be the current size of the file when mmap is called.
 |  flags specifies the nature of the mapping. MAP_PRIVATE creates a
 |  private copy-on-write mapping, so changes to the contents of the mmap
 |  object will be private to this process, and MAP_SHARED creates a mapping
 |  that's shared with all other processes mapping the same areas of the file.
 |  The default value is MAP_SHARED.
 |
 |  To map anonymous memory, pass -1 as the fileno (both versions).
 |
 |  Methods defined here:
 |
 |  __delitem__(self, key, /)
 |      Delete self[key].
 |
 |  __enter__(...)
 |
 |  __exit__(...)
 |
 |  __getattribute__(self, name, /)
 |      Return getattr(self, name).
 |
 |  __getitem__(self, key, /)
 |      Return self[key].
 |
 |  __len__(self, /)
 |      Return len(self).
 |
 |  __setitem__(self, key, value, /)
 |      Set self[key] to value.
 |
 |  __sizeof__(...)
 |      Size of object in memory, in bytes.
 |
 |  close(...)
 |
 |  find(...)
 |
 |  flush(...)
 |
 |  move(...)
 |
 |  read(...)
 |
 |  read_byte(...)
 |
 |  readline(...)
 |
 |  resize(...)
 |
 |  rfind(...)
 |
 |  seek(...)
 |
 |  size(...)
 |
 |  tell(...)
 |
 |  write(...)
 |
 |  write_byte(...)
 |
 |  ----------------------------------------------------------------------
 |  Static methods defined here:
 |
 |  __new__(*args, **kwargs) from builtins.type
 |      Create and return a new object.  See help(type) for accurate signature.
 |
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |
 |  closed
```

頑張れば使えそうな気がしますね！

## 締め

今回の記事はどうでしたでしょうか。

え？そもそも、今どき入力補完の訊く対話型シェル[^1]使う……？
VSCodeからデバッガで雑に書いたコードを実行させて調べる……？
ちゃんと公式ドキュメントとかコード読んでる……？

だから、そんなに困ってない？そっか……