Я хочу, чтобы объект представлял путь root
и произвольное количество подкаталогов, созданных с помощью os.path.join(root)
. Я хочу получить доступ к этим путям в форме self.root
, self.path_a
, self.path_b
и т. Д. ... В дополнение к прямому доступу к ним через self.path_a
, я хочу иметь возможность перебирать их. К сожалению, приведенный ниже подход не позволяет перебирать их через attr.astuple(paths)
Первый фрагмент кода ниже - это то, что я придумал. Это работает, но чувствует себя немного взломанным для меня. Так как это мое первое использование attrs , мне интересно, есть ли более интуитивный / идиоматический способ приблизиться к этому. Мне потребовалось много времени, чтобы понять, как написать довольно простой класс ниже, поэтому я подумал, что могу упустить что-то очевидное.
Мой подход
@attr.s
class Paths(object):
subdirs = attr.ib()
root = attr.ib(default=os.getcwd())
def __attrs_post_init__(self):
for name in self.subdirs:
subdir = os.path.join(self.root, name)
object.__setattr__(self, name, subdir)
def mkdirs(self):
"""Create `root` and `subdirs` if they don't already exist."""
if not os.path.isdir(self.root):
os.mkdir(self.root)
for subdir in self.subdirs:
path = self.__getattribute__(subdir)
if not os.path.isdir(path):
os.mkdir(path)
выход
>>> p = Paths(subdirs=['a', 'b', 'c'], root='/tmp')
>>> p
Paths(subdirs=['a', 'b', 'c'], root='/tmp')
>>> p.a
'/tmp/a'
>>> p.b
'/tmp/b'
>>> p.c
'/tmp/c'
Следующая была моя первая попытка, которая не работает.
Неудачная попытка
@attr.s
class Paths(object):
root = attr.ib(default=os.getcwd())
subdir_1= attr.ib(os.path.join(root, 'a'))
subdir_2= attr.ib(os.path.join(root, 'b'))
выход
------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-31-71f19d55e4c3> in <module>()
1 @attr.s
----> 2 class Paths(object):
3 root = attr.ib(default=os.getcwd())
4 subdir_1= attr.ib(os.path.join(root, 'a'))
5 subdir_2= attr.ib(os.path.join(root, 'b'))
<ipython-input-31-71f19d55e4c3> in Paths()
2 class Paths(object):
3 root = attr.ib(default=os.getcwd())
--> 4 subdir_1= attr.ib(os.path.join(root, 'a'))
5 subdir_2= attr.ib(os.path.join(root, 'b'))
6
~/miniconda3/lib/python3.6/posixpath.py in join(a, *p)
76 will be discarded. An empty last part will result in a path that
77 ends with a separator."""
--> 78 a = os.fspath(a)
79 sep = _get_sep(a)
80 path = a
TypeError: expected str, bytes or os.PathLike object, not _CountingAttr