使用**kwargs初始化类是否存在安全问题?

2024-04-27 04:06:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我最近开始在__init__()中使用**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")

Tags: selfbasedatetimedatemodelthatinitcolumn
2条回答

这是否符合“不必要的副作用”?你知道吗

class Foo(object):
    def __init__(self, name, **kw):
        self.name = name
        for k, v in kw.items():
            setattr(self, k, v)


f = Foo("Bob", __dict__={"aaa":1, "bbb":2, "name":"HEHEHE"})
f.name
>>> 'HEHEHE'

或者为了更有趣:

class Bar(object): 
    pass

f = Foo("Bob", __dict__={"aaa":1, "bbb":2, "name":"HEHEHE"}, __class__=Bar)
type(f)
>>> <class '__main__.Bar'>

现在只要只有可信代码实例化类,这里就没有真正的安全问题——所有这些实际上都可以在初始化器之外完成。但是显式的代码更具可读性,并且可以帮助在这里和那里捕捉到一些拼写错误。你知道吗

受Bruno的启发,您甚至可以覆盖__getattribute____setattr__,有效地使类变得无用

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'

相关问题 更多 >