问题
I have something like:
from attr import attrs, attrib
@attrs
class Foo():
max_count = attrib()
@property
def get_max_plus_one(self):
return self.max_count + 1
Now when I do:
f = Foo(max_count=2)
f.get_max_plus_one =>3
I want to convert this to dict:
{'max_count':2, 'get_max_plus_one': 3}
When I used attr.asdict(f)
I do not get the @property
. I get only
{'max_count':2}
.
What is the cleanest way to achieve the above?
回答1:
For this case, you can use dir
on the object, and get only the properties that do not start with __
i.e. ignore the magic methods:
In [496]: class Foo():
...: def __init__(self):
...: self.max_count = 2
...: @property
...: def get_max_plus_one(self):
...: return self.max_count + 1
...:
In [497]: f = Foo()
In [498]: {prop: getattr(f, prop) for prop in dir(f) if not prop.startswith('__')}
Out[498]: {'get_max_plus_one': 3, 'max_count': 2}
To handle the regular methods that do not start with __
, you can add a callable
test:
In [521]: class Foo():
...: def __init__(self):
...: self.max_count = 2
...: @property
...: def get_max_plus_one(self):
...: return self.max_count + 1
...: def spam(self):
...: return 10
...:
In [522]: f = Foo()
In [523]: {prop: getattr(f, prop) for prop in dir(f) if not (prop.startswith('__') or callable(getattr(Foo, prop, None)))}
Out[523]: {'get_max_plus_one': 3, 'max_count': 2}
回答2:
In general, you would have to iterate over the classes attributes and check for instances of property
and then call the properties __get__
method using the instance. So, something like:
In [16]: class A:
...: @property
...: def x(self):
...: return 42
...: @property
...: def y(self):
...: return 'foo'
...:
In [17]: a = A()
In [18]: vars(a)
Out[18]: {}
In [19]: a.x
Out[19]: 42
In [20]: a.y
Out[20]: 'foo'
In [21]: {n:p.__get__(a) for n, p in vars(A).items() if isinstance(p, property)}
Out[21]: {'x': 42, 'y': 'foo'}
回答3:
I’m afraid that isn’t supported by attrs
at the moment. You may want to follow/comment on https://github.com/python-attrs/attrs/issues/353 which may give you what you want eventually.
来源:https://stackoverflow.com/questions/51733882/how-to-get-property-methods-in-asdict