一、 引言

根据前面章节介绍的内容,我们知道实例变量、实例方法的定义可以通过以下方法进行:

  1. 在类体中直接定义实例变量、实例方法;
  2. 在实例方法中定义实例变量、实例方法;
  3. 在类体外调用方使用赋值语句赋值定义实例变量、实例方法;
  4. 给实例的__dict__字典中插入元素定义实例可以定义实例变量。

    其实还有一种方法,就是调用object类的__setattr__方法,也可以在实例方法或类体外定义实例变量、实例方法。

    二、 调用语法
  5. 调用语法:对象名.setattr( 实例属性名, 值);
  6. 语法释义:

    1)__setattr__方法是由obejct类实现的,各个没有实现该方法的自定义类自动继承,通过调用该方法可以给实例变量的属性赋值或定义一个新的实例属性(含实例变量和方法),本质上就是给实例所在的名字空间字典中添加或修改了一个“属性:值”对;

    2)“对象名”如果是在实例方法中就是“self”,在类体外就是对于实例的名字;

    3)该方法执行没有返回值,执行结果就是新增或者修改了一个“属性”。

三、 案例

  1. 案例说明

    1)定义了函数fdrive,准备用于实例方法定义使用;

    2)定义Car类, 其构造方法中定义了power实例变量和 totaldistance实例变量,不过totaldistance是使用__setattr__方法定义的;

    3)类定义后定义了类的实例car,查看实例的__dict__属性,可见实例属性中可以看到实例变量power和totaldistance;

    4)在类体外使用__setattr__方法将函数绑定到car的实例方法driver。

  2. 源代码

>>> def fdrive(self,distance):self.totaldistance += distance  #定义一个函数,准备用于赋值给类的实例方法属性

>>> class Car():
def __init__(self, power):
self.power = power
self.__setattr__('totaldistance',0) >>> car = Car('汽油发动机')
>>> car.__dict__ #查看自定义实例变量
{'power': '汽油发动机', 'totaldistance': 0}
>>> car.__setattr__('drive',fdrive) #定义实例方法drive
>>> car.__dict__ #查看自定义实例变量
{'power': '汽油发动机', 'totaldistance': 0, 'drive': <function fdrive at 0x0000000003810730>}
>>> car.drive(103) #调用实例方法,由于没有绑定self,因此这样调用报错
Traceback (most recent call last):
File "<pyshell#61>", line 1, in <module>
car.drive(103) #调用实例方法,由于没有绑定self,因此这样调用报错
TypeError: fdrive() missing 1 required positional argument: 'distance'
>>> car.drive(car,103) #调用实例方法drive
>>> car.__dict__ #查看自定义实例变量,可以看到totaldistance值修改了
{'power': '汽油发动机', 'totaldistance': 103, 'drive': <function fdrive at 0x0000000003810730>}
>>>
  1. 执行截图

  2. 案例总结

    从上述案例可以看出,__setattr__方法可以定义实例变量和实例方法,与引言中介绍的几种方法效果一样。

本节结合案例介绍了使用__setattr__方法定义实例变量和实例方法的过程,其本质是与《第8.12节 Python类中使用__dict__定义实例变量和方法》一样的。

老猿Python,跟老猿学Python!

博客地址:https://blog.csdn.net/LaoYuanPython


请大家多多支持,点赞、评论和加关注!谢谢!

第8.28节 Python中使用__setattr__定义实例变量和实例方法的更多相关文章

  1. 第8.20节 Python中限制动态定义实例属性的白名单:__slots__

    一. 引言 按照<第7.10节 Python类中的实例变量定义与使用>.<第7.14节Python类中的实例方法解析>中的介绍,当定义了一个类,并且创建了该类的实例后,可以给该 ...

  2. 第8.12节 Python类中使用__dict__定义实例变量和方法

    上节介绍了使用实例的__dict__查看实例的自定义属性,其实还可以直接使用__dict__定义实例变量和实例方法. 一. 使用__dict__定义实例变量 语法: 对象名. dict[属性名] = ...

  3. python中的类变量、实例变量

    类变量,是各个实例共享的资源,就像中央空调,只有一个,但每个房间(实例)均可享用. 实例变量,是每个实例各自分配使用的变量,每个房间(实例)都有一台空调,供自己使用. class handle(obj ...

  4. 第7.22节 Python中使用super调用父类的方法

    第7.22节 Python中使用super调用父类的方法 前面章节很多地方都引入了super方法,这个方法就是访问超类这个类对象的.由于super方法的特殊性,本节单独谈一谈super方法. 一.su ...

  5. 第7.4节 Python中与众不同的类

    一.    引言 在较旧的Python版本中,类型和类之间泾渭分明:内置对象是基于类型的,而自定义对象是基于类的.因此,你可以创建类,但不能创建类型.在较新的Python 2版本中,这种差别不那么明显 ...

  6. 第7.19节 Python中的抽象类详解:abstractmethod、abc与真实子类

    第7.19节 Python中的抽象类详解:abstractmethod.abc与真实子类 一.    引言 前面相关的章节已经介绍过,Python中定义某种类型是以实现了该类型对应的协议为标准的,而不 ...

  7. 第7.15节 Python中classmethod定义的类方法详解

    第7.15节  Python中classmethod定义的类方法详解 类中的方法,除了实例方法外,还有两种方法,分别是类方法和静态方法.本节介绍类方法的定义和使用. 一.    类方法的定义 在类中定 ...

  8. 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解

    第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一.    引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...

  9. 第8.23节 Python中使用sort/sorted排序与“富比较”方法的关系分析

    一. 引言 <第8.21节 Python中__lt__.gt__等 "富比较"("rich comparison")方法用途探究>和<第8.2 ...

随机推荐

  1. 没有磁盘空间 No space left on device

    INSTALL 的解释文件 帮助文件 这里的 pytorch=1.0.1 torchvision=0.2.2 cudatoolkit=9.0,这个ATSS可以运行. 这里最好能够查看一下cuda的版本 ...

  2. Pycharm激活码亲测有效,2020Pycharm最新激活码免费分享~

    Pycharm激活码,亲测有效!!! 如果下边的Pycharm激活码过期失效了的话,大家可以关注微信公众号:Python联盟,然后回复"激活码"即可获取最新Pycharm永久激活码 ...

  3. deepin 20 镜像源

    deepin 20 镜像源 ## Generated by deepin-installerdeb [by-hash=force] https://community-packages.deepin. ...

  4. linux 进程间通信 共享内存 mmap

    共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间.进程A可以即时看到进程B对共享内存中数据的更新,反 ...

  5. 二、多线程及服务器编程总结------linux多线程服务端编程

  6. fork函数拓展

    1.fork之后父子进程共享文件:文件引用计数的值改变,共享偏移. 在下面的例子中test.txt为parentchil.如果子进程没有睡眠,两个进程交叉执行,内容不可预测. 1 #include&l ...

  7. 线程范围内的环境变量---ThreadLocal

    package cn.itcast.heima2; import java.util.HashMap; import java.util.Map; import java.util.Random; p ...

  8. ceph的jewel新支持的rbd-nbd

    jewel版本新增加了一个驱动NBD,允许librbd实现一个内核级别的rbd NBD相比较于kernel rbd: rbd-ko是根据内核主线走的,升级kernel rbd需要升级到相应的内核,改动 ...

  9. Pinpoint 更改agentid 和 agent name 长度限制(Pinpoint系列二)

    本文基于 Pinpoint 2.1.0 版本 本文的内容为了更改 ID 和 Name 长度限制,因为有使用容器或者是服务名称确实比较长,所以根据业务场景,我们需要更改源码来实现这个. 具体更改,参考 ...

  10. vue中插值表达式中时间转换yyyy-MM-dd HH:mm:ss

    vue插值表达式中将时间转换两种方式:一.定义方法 <div id="app">当前实时时间:{{dateFormat(date)}}</div> //时间 ...