我想要一个代表路径root
和任意数量的子目录的对象,这些子目录是用os.path.join(root)
. 我想用 , , 等形式访问这些路径self.root
...self.path_a
除了self.path_b
直接通过 访问它们之外self.path_a
,我还希望能够遍历它们。不幸的是,下面的方法不允许通过attr.astuple(paths)
下面的第一段代码是我想出的。它有效,但对我来说有点hacky。由于这是我第一次使用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