Python 使用**kwargs初始化类是否存在安全问题?
我最近开始在Python 使用**kwargs初始化类是否存在安全问题?,python,python-2.7,optimization,sqlalchemy,Python,Python 2.7,Optimization,Sqlalchemy,我最近开始在\uuu init\uuuu()中使用**kwargs来初始化对象,因为在添加另一个属性时,我不必对函数进行任何更新。我只是把它们作为参数传递,循环就完成了工作 class Customer(Base): """Model that defines a customer entity""" __tablename__ = "customers" date_created = Column(DateTime) date_modified = Colu
\uuu init\uuuu()
中使用**kwargs
来初始化对象,因为在添加另一个属性时,我不必对函数进行任何更新。我只是把它们作为参数传递,循环就完成了工作
class Customer(Base):
"""Model that defines a customer entity"""
__tablename__ = "customers"
date_created = Column(DateTime)
date_modified = Column(DateTime)
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
但是,根据您的经验,这样做是否存在安全问题?与下面显式定义将初始化什么的代码相比,我们是否会遇到不必要的副作用
class Customer(Base):
"""Model that defines a customer entity"""
__tablename__ = "customers"
date_created = Column(DateTime)
date_modified = Column(DateTime)
def __init__(self, attrs):
self.date_created = attrs.get("date_created")
self.date_modified = attrs.get("date_modified")
这是否符合“不必要的副作用”
或者为了更有趣:
class Bar(object):
pass
f = Foo("Bob", __dict__={"aaa":1, "bbb":2, "name":"HEHEHE"}, __class__=Bar)
type(f)
>>> <class '__main__.Bar'>
类栏(对象):
通过
f=Foo(“Bob”,uuuu dict_uuuuu={“aaa”:1,“bbb”:2,“name”:“HEHEHE”},uuuuuuuu class=Bar)
类型(f)
>>>
现在,只要只有可信代码实例化您的类,这里就没有真正的安全问题——实际上,所有这些都可以在初始化器之外完成。但是显式的代码更具可读性,并且有助于捕捉一些错误。受Bruno的启发,您甚至可以覆盖
\uuuu getattribute\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
class Foo(object):
def __init__(self, name, **kw):
self.name = name
for k, v in kw.items():
setattr(self, k, v)
class Bar(Foo):
def __getattribute__(self, name):
return 'no way'
def __setattr__(self, name, value):
print('aint gonna happen bro')
为此:
>>> f = Foo("Bob", aaa=1, __class__=Bar)
>>> f.aaa
'no way'
>>> f.__class__
'no way'
你甚至无法修复它:
>>> f.__class__ = Foo
aint gonna happen bro
>>> f.__class__
'no way'
无论如何,这几乎就是所做的,只是它在设置之前检查类是否确实具有该属性。因此,只需删除自定义的\uuuuu init\uuuuu
并使用。谢谢@IljaEverilä我在我的SQLAlchemy类中删除了自定义的\uuuu init\uuuuu()
。
>>> f.__class__ = Foo
aint gonna happen bro
>>> f.__class__
'no way'