【发布时间】:2019-04-17 23:15:39
【问题描述】:
我想要一个表示路径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
【问题讨论】:
-
这并不是
attrs的真正用途。你到底想完成什么? -
@roeen30 我对代码示例进行了重大更改,希望更清楚地说明我试图解决的问题。
-
你想做什么更清楚,但不知道为什么。优秀的
pathlib提供了惯用的路径操作 - 如果您还没有,请查看它。由于attrs的主要目标是创建快速记录类,它在这里并不能真正帮助您,因为您有一个具有一个预定属性的类(root)。看起来像是试图通过一个圆孔安装一个方形钉。 -
附带说明,如果您无法避免使用
__get/setattribute__(),则使用getattr()和setattr()内置函数会更清楚。
标签: python python-attrs