Python 自定义 class 迭代器不适用于默认值
Python custom class iterator not working for default values
大家好,我有一个自定义 class MyClass。我想迭代它的默认值。我认为我的问题最好用一个例子来说明:
class MyClass:
def __iter__(self):
for each in self.__dict__.values():
yield each
first_var: str = "asdf"
second_var: str = "tasdt"
my_class = MyClass()
for var in my_class: # this does not work, how can i get this to work?
print(var)
my_class.first_var = "hello" # setting the variables makes it work
my_class.second_var = "world"
for var in my_class: # now it works
print(var)
正如您从示例中看到的那样,第一个 for 循环不打印 class MyClass 的默认值。我怎样才能做到这一点?
编辑:根据我尝试过的 C Hecht 的评论
def __iter__(self):
for attribute in self.__dict__.keys():
if attribute[:2] != '__':
value = getattr(self, attribute)
if not callable(value):
print(attribute, '=', value)
yield value
仍然没有得到那些 class 属性
以上不起作用的原因是 self.__dict__
持有 实例值 。这些通常是通过设置属性添加到 class 的值:
my_class = MyClass()
my_class.__dict__ # {}
my_class.x = 1 # {'x': 1}
如果你想访问 class 属性 first_var
和 second_var
那么你应该查看方法 vars
例如:
for k, v in vars(MyClass.items()):
print(x, y)
# __module__ __main__
# __iter__ <function MyClass.__iter__ at 0x10e22fca0>
# first_val first
# second_var second
# __dict__ <attribute '__dict__' of 'MyClass' objects>
# __weakref__ <attribute '__weakref__' of 'MyClass' objects>
# __doc__ None
如果你只想得到你想要的值,你需要做类似的事情:
def __iter__(self):
for k, v in vars(type(self)).items(): # need type(self) to refer to the class
if not k.startswith('_'):
yield v
问题是因为您迭代的是 class Myclass
的“实例”属性,而不是 class 本身的属性。那些 first_var
和 second_var
是 class 属性:
如果你想获得全部class个属性:
class MyClass:
def __iter__(self):
for each in self.__class__.__dict__.values():
yield each
first_var: str = "asdf"
second_var: str = "tasdt"
my_class = MyClass()
for var in my_class:
print(var)
当然,您可能希望通过是否可调用来过滤它,从 dunder 或 ...
开始
用@dataclass
修饰Pythonclass以实现class实例字段的默认初始化。 It's available 自 Python 3.7 以来,它隐式地将 __init__
构造函数添加到 class 中,后者使用您指定的默认值初始化 class 实例。
from dataclasses import dataclass
@dataclass
class MyClass:
def __iter__(self):
for each in self.__dict__.values():
yield each
first_var: str = "asdf"
second_var: str = "tasdt"
my_class = MyClass()
for var in my_class:
print(var)
打印
asdf
tasdt
大家好,我有一个自定义 class MyClass。我想迭代它的默认值。我认为我的问题最好用一个例子来说明:
class MyClass:
def __iter__(self):
for each in self.__dict__.values():
yield each
first_var: str = "asdf"
second_var: str = "tasdt"
my_class = MyClass()
for var in my_class: # this does not work, how can i get this to work?
print(var)
my_class.first_var = "hello" # setting the variables makes it work
my_class.second_var = "world"
for var in my_class: # now it works
print(var)
正如您从示例中看到的那样,第一个 for 循环不打印 class MyClass 的默认值。我怎样才能做到这一点?
编辑:根据我尝试过的 C Hecht 的评论
def __iter__(self):
for attribute in self.__dict__.keys():
if attribute[:2] != '__':
value = getattr(self, attribute)
if not callable(value):
print(attribute, '=', value)
yield value
仍然没有得到那些 class 属性
以上不起作用的原因是 self.__dict__
持有 实例值 。这些通常是通过设置属性添加到 class 的值:
my_class = MyClass()
my_class.__dict__ # {}
my_class.x = 1 # {'x': 1}
如果你想访问 class 属性 first_var
和 second_var
那么你应该查看方法 vars
例如:
for k, v in vars(MyClass.items()):
print(x, y)
# __module__ __main__
# __iter__ <function MyClass.__iter__ at 0x10e22fca0>
# first_val first
# second_var second
# __dict__ <attribute '__dict__' of 'MyClass' objects>
# __weakref__ <attribute '__weakref__' of 'MyClass' objects>
# __doc__ None
如果你只想得到你想要的值,你需要做类似的事情:
def __iter__(self):
for k, v in vars(type(self)).items(): # need type(self) to refer to the class
if not k.startswith('_'):
yield v
问题是因为您迭代的是 class Myclass
的“实例”属性,而不是 class 本身的属性。那些 first_var
和 second_var
是 class 属性:
如果你想获得全部class个属性:
class MyClass:
def __iter__(self):
for each in self.__class__.__dict__.values():
yield each
first_var: str = "asdf"
second_var: str = "tasdt"
my_class = MyClass()
for var in my_class:
print(var)
当然,您可能希望通过是否可调用来过滤它,从 dunder 或 ...
开始用@dataclass
修饰Pythonclass以实现class实例字段的默认初始化。 It's available 自 Python 3.7 以来,它隐式地将 __init__
构造函数添加到 class 中,后者使用您指定的默认值初始化 class 实例。
from dataclasses import dataclass
@dataclass
class MyClass:
def __iter__(self):
for each in self.__dict__.values():
yield each
first_var: str = "asdf"
second_var: str = "tasdt"
my_class = MyClass()
for var in my_class:
print(var)
打印
asdf
tasdt