Python 作为动态编程语言,可以在任意时刻为一个类实例设置属性,如果不加限制,则可以为一个实例属性设置任意类型的值。但有时我们可能希望对一个新的实例属性的值进行一些自定义的限制或更改,此时就可从 Python 的类定义层面进行考虑了。
其实细细追究下来,Python 中对一个类实例的属性就行访问和设置主要是跟下面 3 个特殊方法有关:
1、__getattr__(self, name):当访问的实例属性不存在于当前类实例的属性字典中时,该方法就会被调用。
2、__getattribute__(self, name):当访问实例属性时,该方法就会被调用,当没有这样的属性时,就会抛出 AttributeError,此时就会调用 __getattr__ 方法。为了避免无穷递归,应该总是调用其父类的 __getattribute__ 方法来获取此属性。
3、__setattr__(self, name, value):当设置实例属性时,该方法就会被调用。为了避免无穷递归,应该总是调用其父类的 __setattr__ 方法来设置此属性。
注意,如果在继承时这几个方法没有被子类覆盖,那么依然会影响到子类。
下面这个例子演示了如何访问一个类实例,以及将新实例属性的值限制为整数。
>>> class T:
def __init__(self, obj):
self.obj = obj # 这里也会调用 __setattr__ 方法
def __getattr__(self, name):
try:
return self.obj[name] # 以 obj 中的值来代替
except KeyError:
raise AttributeError("'T' object has no attribute '%s'" %name)
def __getattribute__(self, name):
return super().__getattribute__(name) # 避免无穷递归
def __setattr__(self, name, value):
print('setting attribute', name)
if name != 'obj' and not isinstance(value, int): # “obj”属性不是整数,需要排除
raise TypeError("value need to be an integer.")
super().__setattr__(name, value) # 避免无穷递归
运行结果:
>>> t = T({'key': 'vvv', 'aa': 'b'})
setting attribute obj
>>>
>>> t.__dict__
{'obj': {'key': 'vvv', 'aa': 'b'}}
>>> t.a # 这里因为属性“a”也不在属性“obj”中
Traceback (most recent call last):
File "<pyshell#132>", line 6, in __getattr__
return self.obj[name]
KeyError: 'a'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<pyshell#135>", line 1, in <module>
t.a
File "<pyshell#132>", line 8, in __getattr__
raise AttributeError("'T' object has no attribute '%s'" %name)
AttributeError: 'T' object has no attribute 'a'
>>> t.aa # aa 在 obj 中
'b'
>>> t.x = 'aaa'
setting attribute x
Traceback (most recent call last):
File "<pyshell#57>", line 1, in <module>
t.x = 'aaa'
File "<pyshell#42>", line 11, in __setattr__
raise TypeError("value need to be an integer.")
TypeError: value need to be an integer.
>>>
>>> t.x = 13
setting attribute x
>>>
>>> t.__dict__
{'obj': {'key': 'vvv', 'aa': 'b'}, 'x': 13}
>>>
分享到:
相关推荐
EXT dojochina Ext类实例属性是一个关于EXT框架在JavaScript中的使用的主题,主要涉及EXT库中的类和实例属性。EXT是一个强大的JavaScript库,用于构建富客户端应用程序,它提供了丰富的组件和布局管理,使得Web应用...
实例属性的优先级高于类属性,如果实例中定义了与类属性同名的属性,将会屏蔽掉类属性。例如: ``` class Student(object): name = 'Student' s = Student() print(s.name) # 打印类的 name 属性 s.name = '...
标题"dotnet-C中使用实例路由设置和访问属性"指出了我们将在C#中通过实例路由来操作类的属性。实例路由允许我们将路由逻辑直接与控制器的实例关联,而不是只与控制器类本身关联。这种方法在处理多个实例时非常有用,...
这里,`Student`类继承了`Person`类,`school`是子类的实例属性,它覆盖了父类可能有的同名属性。 6. **描述符和属性访问机制** Python的属性访问实际上涉及到了描述符协议。当访问一个实例属性时,Python会查找...
实例属性是与特定对象关联的变量,每个对象都有自己的副本。实例属性在初始化方法(通常是`__init__`)中设置,通过`self`关键字引用。 ```python class FireworksDisplay: def __init__(self): self.current_...
在Python编程中,类与对象是面向对象编程的基础。...类属性适用于存储与类相关且不随实例变化的数据,而实例属性则用来存储每个对象特有的状态信息。了解并熟练掌握这些知识,对于编写高效、健壮的Python代码至关重要。
例如,使用`Class.forName()`方法可以获取到任何类的`Class`对象,然后通过这个对象来访问和操作该类的信息。 ```java try { Class<?> clazz = Class.forName("com.example.MyClass"); } catch ...
下面将详细介绍这三个概念以及如何使用它们来设置和获取实例对象的属性值。 **Emit** Emit是.NET Framework中的System.Reflection.Emit命名空间的一部分,它允许我们在运行时动态地创建类型、方法、属性等。Emit...
本实例将详细讲解如何在不同的编程语言中获取和设置这些属性。 在Windows操作系统中,文件属性通常包括只读、隐藏、存档和系统等标志。而在Unix/Linux系统中,文件属性主要包括用户所有权、权限模式(读、写、执行...
`FileInfo`类提供了几个属性来设置文件的特定属性,如`Attributes`属性。这是一个枚举类型`FileAttributes`,包含多种文件属性选项,如`Hidden`、`ReadOnly`、`System`和`Archive`等。以下是如何设置文件为只读和...
对象是类的实例,创建了类的实例意味着可以通过类的实例访问类中的成员。创建对象时,可以通过 new 关键字来创建对象,并且可以通过参数列表来初始化对象的数据成员。 在类设计中,字段、属性、索引器和方法的设计...
总之,Python的`__init__()`方法是初始化实例属性的关键。通过它,我们可以确保每个实例在创建时都有预定义的属性,并且还可以接受任意数量的额外属性,增强了类的灵活性。正确使用`self`参数并结合`**kwargs`关键字...
删除实例属性`s.name`后,实例将再次访问到类属性。 接着,我们讨论实例绑定属性。有两类方式实现这一点:一是通过初始化方法(如`__init__`)中的`self`变量,如`self.name = name`;二是直接给实例赋值,如`s....
Python的`property`属性是一种强大的工具,它允许开发者创建看起来像普通实例属性的访问器方法,但实际上执行了自定义逻辑。这种特性使得代码更加整洁,同时保护了内部数据的完整性,因为可以对属性的访问进行控制和...
例如,`FamilyInstance`类提供访问实例属性的接口,如位置、类型参数等。通过修改这些属性,开发者可以实现动态调整模型元素的功能,如批量更改家具的尺寸或颜色。 在实际应用中,可能需要编写一段代码,例如一个...
// 创建实现接口的类实例 PrintableDocument.Print; // 调用接口方法 end; ``` 这里,`TDocument`实现了`IPrintable`接口,并提供了`Print`方法的具体实现。`TInterfacedObject`是Delphi中的基类,允许类支持COM...
首先,需要创建一个AssemblyBuilder实例来定义程序集,然后添加ModuleBuilder来定义模块,最后利用TypeBuilder创建类并添加字段、属性和方法。 二、动态创建类 创建类的核心在于TypeBuilder类。通过TypeBuilder,...
例如,`Type`类可以用来获取一个对象的类型信息,`PropertyInfo`类则用于访问和操作属性。通过`GetProperty`方法,我们可以获取指定名称的属性,并使用`GetValue`和`SetValue`来读写属性值。 但是,反射的缺点在于...
在本篇文章提供的代码示例中,通过include_once语句引入了AdodbZip.php文件,并通过init方法初始化AdodbZip类实例。随后使用该实例执行SQL查询,并输出结果。这种方式演示了Adodbzip类结合ADOdb实现数据库操作的基本...