gpt4 book ai didi

Python 元类默认属性

转载 作者:行者123 更新时间:2023-11-28 16:47:47 26 4
gpt4 key购买 nike

我正在尝试在 Python (2.7) 中创建元类,它将设置传递给对象的 __init__ 的参数作为对象属性。

class AttributeInitType(type):        
def __call__(self, *args, **kwargs):
obj = super(AttributeInitType, self).__call__(*args, **kwargs)
for k, v in kwargs.items():
setattr(obj, k, v)
return obj

用法:

class Human(object):
__metaclass__ = AttributeInitType

def __init__(self, height=160, age=0, eyes="brown", sex="male"):
pass

man = Human()

问题:我希望man 实例的默认属性设置为类的__init__。我该怎么做?

更新:我找到了更好的解决方案:

  • 在类创建期间仅检查一次__init__ 方法
  • 不会覆盖(可能)由类的真实 __init__ 设置的属性

代码如下:

import inspect
import copy

class AttributeInitType(type):
"""Converts keyword attributes of the init to object attributes"""
def __new__(mcs, name, bases, d):
# Cache __init__ defaults on a class-level
argspec = inspect.getargspec(d["__init__"])
init_defaults = dict(zip(argspec.args[-len(argspec.defaults):], argspec.defaults))
cls = super(AttributeInitType, mcs).__new__(mcs, name, bases, d)
cls.__init_defaults = init_defaults
return cls

def __call__(mcs, *args, **kwargs):
obj = super(AttributeInitType, mcs).__call__(*args, **kwargs)
the_kwargs = copy.copy(obj.__class__.__init_defaults)
the_kwargs.update(kwargs)
for k, v in the_kwargs.items():
# Don't override attributes set by real __init__
if not hasattr(obj, k):
setattr(obj, k, v)
return obj

最佳答案

您需要检查 __init__ 方法并从那里提取任何默认值。 getargspec function在那里会有帮助。

getargspec 函数返回(以及其他)参数名称列表和默认值列表。您可以结合这些来找到给定函数的默认参数规范,然后使用该信息来设置对象的属性:

import inspect

class AttributeInitType(type):
def __call__(self, *args, **kwargs):
obj = super(AttributeInitType, self).__call__(*args, **kwargs)
argspec = inspect.getargspec(obj.__init__)
defaults = dict(zip(argspec.args[-len(argspec.defaults):], argspec.defaults))
defaults.update(kwargs)
for key, val in defaults.items():
setattr(obj, key, val)
return obj

使用上面的元类,您可以省略任何参数,它们将在新实例上设置,或者您可以通过显式传递它们来覆盖它们:

>>> man = Human()
>>> man.age
0
>>> man.height
160
>>> Human(height=180).height
180

关于Python 元类默认属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12036367/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com