在 __init__ 中使用 **kwargs
using **kwargs in __init__
我 运行 遇到以下问题:
class Student():
def __init__(self,firstname, lastname, **kwargs):
self.firstname = firstname
self.lastname = lastname
student1 = Student("John" ,"Johnson" , {"Nationality": "Middle-Earth" , "Sports": ["volleyball","skiing"]})
我希望能够创建所有都有名字和姓氏的学生,但只有一些学生有关于国籍或运动的信息。 (实际上,我正在尝试从 json 文件中重建对象。)
所以我想把kwarg key变成实例变量名,就像这个伪代码
for key,value in kwargs:
self.key = value
上面是伪代码,但是有没有办法正确地做到这一点python?换句话说:从 kwargs 派生实例变量名而不是所有预定义的。
我知道这不会产生防错代码等...,但我想知道是否可以做到。
您需要将解压缩的 kwargs 传递给 Student
并使用 setattr(object, name, value)
设置值:
class Student():
def __init__(self,firstname, lastname, **kwargs):
self.firstname = firstname
self.lastname = lastname
for (k,v) in kwargs.items():
setattr(self, k, v)
student1 = Student("John" ,"Johnson" , **{"Nationality": "Middle-Earth" , "Sports": ["volleyball","skiing"]})
print(student1.__dict__)
输出:
{'lastname': 'Johnson', 'Sports': ['volleyball', 'skiing'], 'firstname': 'John', 'Nationality': 'Middle-Earth'}
您可以在 __init__
方法中使用它:
for k, v in kwargs.items():
setattr(self, k, v)
但是,对于需要可重用的代码,不建议这样做。如果关键字参数中有拼写错误,您将无法捕捉到它们。 pylint 等代码检查工具无法识别像这样初始化的 class 属性。您可以使用以下模式(尤其是在有很多关键字参数的情况下):
class Student:
def __init__(self, firstname, lastname, **kwargs):
self.firstname = str(firstname)
self.lastname = str(lastname)
self.nationality = None
self.sports = None
for k, v in kwargs.items():
if k in self.__dict__:
setattr(self, k, v)
else:
raise KeyError(k)
# this works
s=Student('John', 'Doe', sports=['socker'])
# this will give an error
s=Student('John', 'Doe', sprots=['socker'])
我建议预先说明实例可以具有哪些属性,并使用 None
之类的标记值来指示缺少 "real" 值而不是完全消除该属性。例如:
class Student():
def __init__(self,firstname, lastname, nationality=None, sports=None):
self.firstname = firstname
self.lastname = lastname
self.nationality = nationality
self.sports = [] if sports is None else sports
然后
student1 = Student("John" ,"Johnson" , "Middle-Earth" , ["volleyball","skiing"])
student2 = Student("Bob", "Smith", nationality="Australia") # No sports
student3 = Student("Alice", "Doe", sports=["hockey"]) # No nationality
如果你想解析 JSON 可能有与你的参数名称不匹配的键名,定义一个 class 方法来进行处理以获得适当的参数。例如,
@classmethod
def from_dict(cls, data):
firstname = data["FirstName"]
lastname = data["some last name"]
nationality = data.get("Nationality")
sports = data.get("Sports", [])
return cls(firstname, lastname, nationality, sports)
然后
student = Student.from_dict({'FirstName': 'John', 'some_last_name': 'Doe',})
我 运行 遇到以下问题:
class Student():
def __init__(self,firstname, lastname, **kwargs):
self.firstname = firstname
self.lastname = lastname
student1 = Student("John" ,"Johnson" , {"Nationality": "Middle-Earth" , "Sports": ["volleyball","skiing"]})
我希望能够创建所有都有名字和姓氏的学生,但只有一些学生有关于国籍或运动的信息。 (实际上,我正在尝试从 json 文件中重建对象。) 所以我想把kwarg key变成实例变量名,就像这个伪代码
for key,value in kwargs:
self.key = value
上面是伪代码,但是有没有办法正确地做到这一点python?换句话说:从 kwargs 派生实例变量名而不是所有预定义的。
我知道这不会产生防错代码等...,但我想知道是否可以做到。
您需要将解压缩的 kwargs 传递给 Student
并使用 setattr(object, name, value)
设置值:
class Student():
def __init__(self,firstname, lastname, **kwargs):
self.firstname = firstname
self.lastname = lastname
for (k,v) in kwargs.items():
setattr(self, k, v)
student1 = Student("John" ,"Johnson" , **{"Nationality": "Middle-Earth" , "Sports": ["volleyball","skiing"]})
print(student1.__dict__)
输出:
{'lastname': 'Johnson', 'Sports': ['volleyball', 'skiing'], 'firstname': 'John', 'Nationality': 'Middle-Earth'}
您可以在 __init__
方法中使用它:
for k, v in kwargs.items():
setattr(self, k, v)
但是,对于需要可重用的代码,不建议这样做。如果关键字参数中有拼写错误,您将无法捕捉到它们。 pylint 等代码检查工具无法识别像这样初始化的 class 属性。您可以使用以下模式(尤其是在有很多关键字参数的情况下):
class Student:
def __init__(self, firstname, lastname, **kwargs):
self.firstname = str(firstname)
self.lastname = str(lastname)
self.nationality = None
self.sports = None
for k, v in kwargs.items():
if k in self.__dict__:
setattr(self, k, v)
else:
raise KeyError(k)
# this works
s=Student('John', 'Doe', sports=['socker'])
# this will give an error
s=Student('John', 'Doe', sprots=['socker'])
我建议预先说明实例可以具有哪些属性,并使用 None
之类的标记值来指示缺少 "real" 值而不是完全消除该属性。例如:
class Student():
def __init__(self,firstname, lastname, nationality=None, sports=None):
self.firstname = firstname
self.lastname = lastname
self.nationality = nationality
self.sports = [] if sports is None else sports
然后
student1 = Student("John" ,"Johnson" , "Middle-Earth" , ["volleyball","skiing"])
student2 = Student("Bob", "Smith", nationality="Australia") # No sports
student3 = Student("Alice", "Doe", sports=["hockey"]) # No nationality
如果你想解析 JSON 可能有与你的参数名称不匹配的键名,定义一个 class 方法来进行处理以获得适当的参数。例如,
@classmethod
def from_dict(cls, data):
firstname = data["FirstName"]
lastname = data["some last name"]
nationality = data.get("Nationality")
sports = data.get("Sports", [])
return cls(firstname, lastname, nationality, sports)
然后
student = Student.from_dict({'FirstName': 'John', 'some_last_name': 'Doe',})