如何获取class中变量的所有值?
How to get all values of variables in class?
class NiceClass():
some_value = SomeObject(...)
some_other_value = SomeOtherObject(...)
@classmethod
def get_all_vars(cls):
...
我想要get_all_vars()
到return[SomeObject(...), SomeOtherObject(...)]
,或者更具体地说,cls
.中变量的值
尝试过但对我不起作用的解决方案:
return [cls.some_value, cls.some_other_value, ...]
(需要手动列出变量)
- 子类化
Enum
然后使用 list(cls)
(需要使用 some_value.value
来访问程序中其他地方的值,类型提示也会一团糟)
- namedtuples(不涉及那个主题,听说它比
Enum
复杂得多)
[value for key, value in vars(cls).items() if not callable(value) and not key.startswith("__")]
(由于使用 vars(cls)
太老套了,而且出于某种原因它还包含 get_all_vars
因为它是 classmethod
)
这听起来可能像 https://xyproblem.info/ but my solution might work in the other case as well. You can get the fields of an object by using __dict__
or vars
(which is considered more pythonic given: Python dictionary from an object's fields)
你可以这样做:
class ClassTest:
def __init__(self):
self.one = 1
self.two = 2
list(vars(ClassTest()).values())
但是您会发现它有一些局限性。它无法识别 not in self.variable_name
定义的变量,就像您在上面使用的那样。尽管如此,它可能对您有所帮助,因为您可以简单地在 init 中定义它们。
有两种方法。这是对您问题的直接回答:
class Foo:
pass
class Bar:
x: int = 1
y: str = 'hello'
z: Foo = Foo()
@classmethod
def get_all(cls):
xs = []
for name, value in vars(cls).items():
if not (name.startswith('__') or isinstance(value, classmethod)):
xs.append(value)
return xs
这是我的建议:
from dataclasses import dataclass, fields
class Foo:
pass
@dataclass
class Bar:
x: int = 1
y: str = 'hello'
z: Foo = Foo()
@classmethod
def get_defaults(cls):
return [f.default for f in fields(cls)]
@classmethod
def get_all(cls):
return [getattr(cls, f.name) for f in fields(cls)]
结果:
Bar.get_defaults() == Bar.get_all()
# True -> [1, 'hello', __main__.Foo]
Bar.x = 10
Bar.get_defaults() == Bar.get_all()
# False -> [1, 'hello', __main__.Foo] != [10, 'hello', __main__.Foo]
您可以创建一个值列表 和 同时使用最少的样板文件定义各个属性。
class NiceClass():
(some_value,
some_other_value,
) = _all_values = [
SomeObject(...),
SomeOtherObject(...)
]
@classmethod
def get_all_vars(cls):
return cls._all_values
这样做最明显的缺点是很容易使名称和值的顺序不同步。
理想情况下,您可能喜欢做类似
的事情
class NiceClass:
_attributes = {
'some_value': SomeObject(...),
'some_other_value': SomeOtherObject(...)
}
@classmethod
def get_all_vars(cls):
return cls._attributes.values()
并有一些方法可以将 _attributes
的内容直接“注入”到 class 命名空间中。最简单的方法是使用 mix-in class 定义 __init_subclass__
:
class AddAttributes:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.__dict__.update(cls._attributes)
class NiceClass(AddAttributes):
# As above
...
class NiceClass():
some_value = SomeObject(...)
some_other_value = SomeOtherObject(...)
@classmethod
def get_all_vars(cls):
...
我想要get_all_vars()
到return[SomeObject(...), SomeOtherObject(...)]
,或者更具体地说,cls
.中变量的值
尝试过但对我不起作用的解决方案:
return [cls.some_value, cls.some_other_value, ...]
(需要手动列出变量)- 子类化
Enum
然后使用list(cls)
(需要使用some_value.value
来访问程序中其他地方的值,类型提示也会一团糟) - namedtuples(不涉及那个主题,听说它比
Enum
复杂得多) [value for key, value in vars(cls).items() if not callable(value) and not key.startswith("__")]
(由于使用vars(cls)
太老套了,而且出于某种原因它还包含get_all_vars
因为它是classmethod
)
这听起来可能像 https://xyproblem.info/ but my solution might work in the other case as well. You can get the fields of an object by using __dict__
or vars
(which is considered more pythonic given: Python dictionary from an object's fields)
你可以这样做:
class ClassTest:
def __init__(self):
self.one = 1
self.two = 2
list(vars(ClassTest()).values())
但是您会发现它有一些局限性。它无法识别 not in self.variable_name
定义的变量,就像您在上面使用的那样。尽管如此,它可能对您有所帮助,因为您可以简单地在 init 中定义它们。
有两种方法。这是对您问题的直接回答:
class Foo:
pass
class Bar:
x: int = 1
y: str = 'hello'
z: Foo = Foo()
@classmethod
def get_all(cls):
xs = []
for name, value in vars(cls).items():
if not (name.startswith('__') or isinstance(value, classmethod)):
xs.append(value)
return xs
这是我的建议:
from dataclasses import dataclass, fields
class Foo:
pass
@dataclass
class Bar:
x: int = 1
y: str = 'hello'
z: Foo = Foo()
@classmethod
def get_defaults(cls):
return [f.default for f in fields(cls)]
@classmethod
def get_all(cls):
return [getattr(cls, f.name) for f in fields(cls)]
结果:
Bar.get_defaults() == Bar.get_all()
# True -> [1, 'hello', __main__.Foo]
Bar.x = 10
Bar.get_defaults() == Bar.get_all()
# False -> [1, 'hello', __main__.Foo] != [10, 'hello', __main__.Foo]
您可以创建一个值列表 和 同时使用最少的样板文件定义各个属性。
class NiceClass():
(some_value,
some_other_value,
) = _all_values = [
SomeObject(...),
SomeOtherObject(...)
]
@classmethod
def get_all_vars(cls):
return cls._all_values
这样做最明显的缺点是很容易使名称和值的顺序不同步。
理想情况下,您可能喜欢做类似
的事情class NiceClass:
_attributes = {
'some_value': SomeObject(...),
'some_other_value': SomeOtherObject(...)
}
@classmethod
def get_all_vars(cls):
return cls._attributes.values()
并有一些方法可以将 _attributes
的内容直接“注入”到 class 命名空间中。最简单的方法是使用 mix-in class 定义 __init_subclass__
:
class AddAttributes:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
cls.__dict__.update(cls._attributes)
class NiceClass(AddAttributes):
# As above
...