[英]Any way to get all possible Python class variables, including ones without values?
I'm creating a class to represent a query, like this:我正在创建一个类来表示查询,如下所示:
class Query:
height: int
weight: int
age: int
name: str
is_alive: bool = True
As you can see, some variables start off initialized with defaults, others don't.如您所见,一些变量开始时使用默认值进行初始化,而其他变量则没有。
I want to implement chainable setters like so我想像这样实现可链接的设置器
def of_height(self, height):
self.height = height
return self
def with_name(self, name):
self.name = name
return self
...
The goal is to call this from several places in the project like so:目标是从项目中的几个地方调用它,如下所示:
q = Query()
q.of_height(175).with_name("Alice")
Then I want to call a q.validate()
that checks if any fields were not set, before calling an API with this query.然后我想调用一个q.validate()
来检查是否未设置任何字段,然后再使用此查询调用 API。
I can't figure out a way to dynamically check all possible variables, set or not, to check if any were left unset.我想不出一种方法来动态检查所有可能的变量,无论是否设置,以检查是否有任何未设置。 Ideally, I don't want to implement a validate
that has to be changed every time I add a possible query dimension in this class.理想情况下,我不想实现每次在此类中添加可能的查询维度时都必须更改的validate
。
The variable annotations collected during class body execution are stored in an __annotations__
attribute which you can use.在类主体执行期间收集的变量注释存储在您可以使用的__annotations__
属性中。
>>> Query.__annotations__
{'height': int, 'weight': int, 'age': int, 'name': str, 'is_alive': bool}
This is documented in the datamodel under the "Custom classes" section.这记录在“自定义类”部分下的数据模型中。
Usually, you would not access this attribute directly but use inspect.get_annotations
instead, which provides a few conveniences.通常,您不会直接访问此属性,而是使用inspect.get_annotations
代替,这提供了一些便利。
Following on @wim's solution, it would be desirable to get annotations from self
so that a validate
method will work with subclasses.在@wim 的解决方案之后,最好从self
获取注释,以便validate
方法可以与子类一起使用。 Following is an implementation using inspect.get_annotations
- but note that its a 3.10 feature.以下是使用inspect.get_annotations
的实现 - 但请注意,它是 3.10 功能。
#!/usr/bin/env python3.10
import inspect
import itertools
class Query:
height: int
weight: int
age: int
name: str
is_alive: bool = True
class Query2(Query):
foo: int
def get_annotated_attrs(self):
return set(itertools.chain.from_iterable(inspect.get_annotations(Q).keys() for Q in self.__class__.__mro__))
def validate(self):
for name in self.get_annotated_attrs():
if not hasattr(self, name):
return False
return True
q2 = Query2()
print(q2.get_annotated_attrs())
print(q2.validate())
I was thinking of something like this我在想这样的事情
import inspect
class Query:
height: int
weight: int
age: int
name: str
is_alive: bool = True
avilable_dimentions = ['height', 'weight', 'age', 'name', 'is_alive']
def of_height(self, height):
self.height = height
return self
def with_name(self, name):
self.name = name
return self
def validate(self):
not_defined = []
for dim in self.avilable_dimentions:
try:
eval(f'self.{dim}')
except:
not_defined.append(dim)
if not_defined:
raise Exception(f'Missing dimentions {not_defined}')
return self
class Query2(Query):
height2: int
weight2: int
avilable_dimentions = Query.avilable_dimentions + ['height2', 'weight2']
q = Query2()
q = q.of_height(175).with_name("Alice").validate()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.