如何在python中动态创建类变量

发布于 2024-12-18 12:52:03 字数 269 浏览 0 评论 0原文

我需要创建一堆类变量,我想通过循环遍历这样的列表来完成它:

vars = ('tx', 'ty', 'tz')  # plus plenty more

class Foo():
    for v in vars:
        setattr(no_idea_what_should_go_here, v, 0)

可能吗?我不想将它们作为实例(在 __init__ 中使用 self),而是作为类变量。

I need to make a bunch of class variables and I would like to do it by looping through a list like that:

vars = ('tx', 'ty', 'tz')  # plus plenty more

class Foo():
    for v in vars:
        setattr(no_idea_what_should_go_here, v, 0)

is it possible? I don't want to make them for an instance (using self in the __init__) but as class variables.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

高速公鹿 2024-12-25 12:52:04

您可以在创建类后立即运行插入代码:

class Foo():
     ...

vars = ('tx', 'ty', 'tz')  # plus plenty more
for v in vars:
    setattr(Foo, v, 0)

此外,您可以在创建类时动态存储变量:

class Bar:
    locals()['tx'] = 'texas'

You can run the insertion code immediately after a class is created:

class Foo():
     ...

vars = ('tx', 'ty', 'tz')  # plus plenty more
for v in vars:
    setattr(Foo, v, 0)

Also, you can dynamically store the variable while the class is being created:

class Bar:
    locals()['tx'] = 'texas'
追星践月 2024-12-25 12:52:04

使用 type 类构造函数

Foo = type("Foo", (), {k: 0 for k in ("tx", "ty", "tz")})

Use the type class constructor!

Foo = type("Foo", (), {k: 0 for k in ("tx", "ty", "tz")})
相思碎 2024-12-25 12:52:04

如果出于任何原因您不能使用雷蒙德在类创建后设置它们的答案,那么也许您可以使用元类:

class MetaFoo(type):
    def __new__(mcs, classname, bases, dictionary):
        for name in dictionary.get('_extra_vars', ()):
            dictionary[name] = 0
        return type.__new__(mcs, classname, bases, dictionary)
    
class Foo():  # For python 3.x use 'class Foo(metaclass=MetaFoo):'
    __metaclass__ = MetaFoo  # For Python 2.x only
    _extra_vars = 'tx ty tz'.split()

If for any reason you can't use Raymond's answer of setting them up after the class creation then perhaps you could use a metaclass:

class MetaFoo(type):
    def __new__(mcs, classname, bases, dictionary):
        for name in dictionary.get('_extra_vars', ()):
            dictionary[name] = 0
        return type.__new__(mcs, classname, bases, dictionary)
    
class Foo():  # For python 3.x use 'class Foo(metaclass=MetaFoo):'
    __metaclass__ = MetaFoo  # For Python 2.x only
    _extra_vars = 'tx ty tz'.split()
╰◇生如夏花灿烂 2024-12-25 12:52:04

setattr(对象、名称、值)

这个是 getattr() 的对应项。参数是一个对象、一个字符串和一个任意值。该字符串可以命名现有属性或新属性。如果对象允许,该函数会将值分配给属性。

例如,这些是等效的:

setattr(x, 'name', value)
x.name = value

setattr(object, name, value)

This is the counterpart of getattr(). The arguments are an object, a string and an arbitrary value. The string may name an existing attribute or a new attribute. The function assigns the value to the attribute, provided the object allows it.

For example, these are equivalent:

setattr(x, 'name', value)
x.name = value
听风吹 2024-12-25 12:52:04

locals() 版本在课堂上对我不起作用。

以下可用于动态创建类的属性:

class namePerson:
    def __init__(self, value):
        exec("self.{} = '{}'".format("name", value)

me = namePerson(value='my name')
me.name # returns 'my name'

The locals() version did not work for me in a class.

The following can be used to dynamically create the attributes of the class:

class namePerson:
    def __init__(self, value):
        exec("self.{} = '{}'".format("name", value)

me = namePerson(value='my name')
me.name # returns 'my name'
雪若未夕 2024-12-25 12:52:04

您需要的函数是:

setattr(obj, name, value)

这允许您为给定类设置命名属性(可以是 self)。

此函数的内置文档非常不言自明:

Signature: setattr(obj, name, value, /)
Docstring:
Sets the named attribute on the given object to the specified value.

setattr(x, 'y', v) is equivalent to ``x.y = v''
Type:      builtin_function_or_method

示例使用

此功能的一种用途是使用字典来设置多个类属性,在我的例子中,这是来自 xpath 定义。我觉得通过将可能更脆弱的 xpath 定义全部保留在一个地方,可以提高可维护性:

class Person:
    def _extract_fields(self):
        ''' Process the page using XPath definitions '''
        logging.debug("_extract_fields(): {}".format(repr(self)))
        # describe how to extract data from the publicly available site
        # (kept together for maintainability)
        fields = {
            'staff_name':
            '//div[@id="staff_name"]//text()',
            'staff_dob':
            '(//div[@id="staff_dob"]//text())[1]'
        }
        # populate named class attributes from the dict
        for key in fields:
            setattr(self, key, self._parsed_content.xpath(fields[key]))

    def __init__(self):
        self._extract_fields()

The function you need is:

setattr(obj, name, value)

This allows you to set named attributes for a given class (this can be self).

The built in documentation for this function is pretty self-explanatory:

Signature: setattr(obj, name, value, /)
Docstring:
Sets the named attribute on the given object to the specified value.

setattr(x, 'y', v) is equivalent to ``x.y = v''
Type:      builtin_function_or_method

Example use

One use of this is to use a dictionary to set multiple class attributes, in my case this was from xpath definitions. I felt this improved maintainability by keeping potentially more fragile xpath definitions all in one place:

class Person:
    def _extract_fields(self):
        ''' Process the page using XPath definitions '''
        logging.debug("_extract_fields(): {}".format(repr(self)))
        # describe how to extract data from the publicly available site
        # (kept together for maintainability)
        fields = {
            'staff_name':
            '//div[@id="staff_name"]//text()',
            'staff_dob':
            '(//div[@id="staff_dob"]//text())[1]'
        }
        # populate named class attributes from the dict
        for key in fields:
            setattr(self, key, self._parsed_content.xpath(fields[key]))

    def __init__(self):
        self._extract_fields()
迷爱 2024-12-25 12:52:04

您可以使用“foo”创建全局变量。 (或您的班级名称)位于名称的开头:

vars=('tx','ty','tz') #plus plenty more

class Foo():
    pass

foo = Foo() # Instance the class

for i in vars:
    globals () ["foo." + i] = value

You can create global variables with "foo." (or the name of your class) at the beggining of the name:

vars=('tx','ty','tz') #plus plenty more

class Foo():
    pass

foo = Foo() # Instance the class

for i in vars:
    globals () ["foo." + i] = value
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文