在 Python 中设置类的属性

Dhruvdeep Singh Saini 2023年1月30日 2022年5月18日
  1. 在 Python 中使用 setattr() 函数设置类的属性
  2. 在 Python 中何处使用 Set 属性
  3. 在 Python 中如何使用 setattr() 为类添加新属性
  4. 为什么在类中使用 Set 属性会导致 Python 中的递归
  5. 如何正确使用 Set Attribute 来避免 Python 中的无限递归错误
  6. 如何修复 MicroPython 中的递归错误
  7. 结论
在 Python 中设置类的属性

Python 的 setattr() 方法来自 PEP383,允许它动态控制和访问属性以更改其值。

在 Python 中使用 setattr() 函数设置类的属性

Python 的 setattr() 函数用于设置类属性的值。在编程中,变量名称不是静态的,setattr() 方法非常方便,因为它提供了易用性。

Python 中设置属性的语法

设置属性技术可作为利用构造函数和对象方法的替代方法。它可用于在进行属性分配时通过执行 setattr() 将参数传递给属性。

set 属性的语法如下。

setattr(self, name, value)

上面的语法指定了以下三件事。

  • self - 你分配其属性的对象的名称。
  • name - 分配变量的名称。
  • value - 分配变量的值。

设置属性返回 None。请注意,你只能提供字符串作为属性的名称。

在 Python 中何处使用 Set 属性

让我们演示 setattr()baskets 类的用法,并使用 setattr() 方法提供其值。

class Baskets:
  fruit = 'Plum'

bas = Baskets()
print("Old fruit: ")
print(bas.fruit)

setattr(bas, 'fruit', 'Apple')

print("Fruit Now is: ")
print(bas.fruit)

输出:

Old fruit:
Plum
Fruit Now is:
Apple

Baskets 类有一个水果。setattr() 函数已被调用一次以更改篮子的水果。

在 Python 中如何使用 setattr() 为类添加新属性

如果要向类添加新字段,可以使用具有相同语法的 setattr() 方法。

setattr() 在现有类中添加一个新变量,并在类中不出现给定变量时设置所述数据。

class Baskets:
  fruit = 'Banana'
  vegetable = 'Potato'

bas = Baskets()

# Adding candy to the basket
setattr(bas, 'candy', 'Kit Kat')
print('Added:', bas.candy)

输出:

Added: Kit Kat

即使我们从上面的代码中删除了一个属性,我们仍然可以在之后使用 setattr() 添加它。

Python 中设置属性的不同语法

setattr(object,name,value) 是更短的语法,而不是使用 object.__setattr__(name, value),使两种方法相同。

object.__setattr__() 在类定义中,并使用 super() 获取下一个属性。

上面的语法在两种情况下无效。

  • 对象已经有一个预定义的字典 __setattr__ 方法,由错误引起。
  • 对象的类也有一个 __getattr__(获取属性)方法。__getattr__ 方法会阻止所有搜索,无论属性是否存在。

为什么在类中使用 Set 属性会导致 Python 中的递归

目的是在创建成员参数并设置成员参数时调用例程时执行代码。

对已删除值和属性分配的所有更新都会更改实例字典,而不是实际类。

如果在这种情况下已设置实例字典,则直接调用 __setattr__ 方法来更新实例字典。

如果你使用以下语法会出现问题:self.name = value __setattr__() 写入实例变量,因为这将是递归操作。它会导致 Python 中的递归错误。

如何正确使用 Set Attribute 来避免 Python 中的无限递归错误

有时使用 __setattr__ 会导致编码错误,例如无限递归循环。

如果你想在定义包含读写方法的类时避免使用交错类,你可以覆盖 __setattr__ 方法。

但是,如上所述,__init__ 函数可能会导致不必要的递归冲突。这是因为 __setattr__ 不断被调用。

class StAttrTest(object):

    def __init__ ( self , run1 ):
        self.run1 = run1
    #setattr method with if else
    def __setattr__ (self , name , value):

        if name == " Lenn1 ":
            print ("Lenn1 test")
        else:
            setattr(self , name , value)

cm = StAttrTest(1)

当你执行上述程序时,此代码会运行,但会陷入无休止的递归错误。

有多种方法可以消除无限循环循环。

  1. 在类定义中添加 @property 装饰器,如下所示。
@property
def device(self):
    return self

Python 提供了@property 功能来访问公共变量等实例变量,同时利用现有的 getter 和 setter 来确认更新的值并防止显式访问或数据操作。

  1. 通过删除 __init__ 方法中的 example 属性可以快速解决该问题。
class AttrTest(object):
   #init without extra attribute
   def __init__(self):
	   self.device = self

上述方法解决了这个问题,但不是一个好的做法,只是一个快速修复。

  1. 也可以直接在 set 属性方法下使用对象。
object.__setattr__(self, name, value)

MicroPython 有时不接受上述解决方案,因此需要不同的方法。MicroPython 是一种重新实现,力求尽可能保持一致,允许开发人员将代码从计算机快速移动到微处理器或集成设备。

如果你是高级编码员,你可以按照以下修复设置属性方法出现的递归错误。

如何修复 MicroPython 中的递归错误

此方法涉及使用 object.__dict__ 交替对象的字典值。该技术包括在 __setattr__ 方法中更新对象的字典值。

class StAtrTest(object):
   #setattr with object's dictionary overridden
   def __setattr__(self, name, value):
	   print(name, value)
	   self.__dict__[name] = value

   def __init__(self, var_O):
	   self.var_O = var_O
#Testing
up = StAtrTest(var_O=17)
#Changing
up.var_O = 218

输出:

var_O 17
var_O 218

这里描述的方法通常被认为是解决 Python 和 MicroPython 中无限递归错误的最有效技术。

结论

这个内容丰富的指南使用 Python 的 set 属性方法进行了讨论,这是一种在字典实例中写入属性和更新类变量以进行简洁编码的极好方法。

本文提供了在 Python 中使用 __setattr__ 的各种有效方法,以便你在设计具有读写方法的类时不会陷入无限递归错误。它还强调了 setattr()__setattr__ 方法之间的区别。

请记住,最好和推荐的方法是使用 object.__dict__