基于Python 2.7.13测试。

  

  Python是动态语言,在类定义了之后,还可以动态地绑定属性和方法。

  下面先来看怎么给类的实例动态地绑定属性和方法。

>>> class Student(object):
... pass
...
>>> stu1 = Student();
>>> stu1.name = 'Tom'
>>> print(stu1.name)
Tom
>>> print(dir(stu1))
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribut
e__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_e
x__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_
_weakref__', 'name']
>>>
>>> def set_age(self, age):
... self.age = age
...
>>> set_age(stu1, 20)
>>> print(stu1.age)
20
>>> print(dir(stu1))
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribut
e__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_e
x__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_
_weakref__', 'age', 'name']
>>> #并没有绑定方法到实例上
...
>>> from types import MethodType
>>> stu1.set_age = MethodType(set_age, stu1)
>>> stu1.set_age(33)
>>> print(stu1.age)
33
>>> print(dir(stu1))
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribut
e__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_e
x__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_
_weakref__', 'age', 'name', 'set_age']
>>> #绑定的属性和方法只属于stu1的,对于其他实例不起作用
...
>>> stu2 = Student()
>>> print(dir(stu2))
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribut
e__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_e
x__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_
_weakref__']

  看怎么给类动态地绑定属性和方法。

>>> class Student(object):
... pass
...
>>> def set_name(self, name):
... self.name = name
...
>>> from types import MethodType
>>> Student.set_name = MethodType(set_name, Student)
>>> print(dir(Student))
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribut
e__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_e
x__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_
_weakref__', 'set_name']
>>> stu1 = Student()
>>> stu1.set_name('Rose')
>>> stu2 = Student()
>>> stu2.set_name('Jack')
>>> print(stu1.name)
Jack
>>> print(stu2.name)
Jack
>>> ########
>>> class Student(object):
... pass
...
>>> def set_name(self, name):
... self.name = name
...
>>> Student.set_name = set_name
>>> print(dir(Student))
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribut
e__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_e
x__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_
_weakref__', 'set_name']
>>> stu1 = Student()
>>> stu1.set_name('Rose')
>>> stu2 = Student()
>>> stu2.set_name('Jack')
>>> print(stu1.name)
Rose
>>> print(stu2.name)
Jack

  想要限制实例属性,只允许对Student实例添加name和age属性。__slots__变量,来限制该class实例能添加的属性。

>>> class Student(object):
... __slots__ = ('name', 'age')
...
>>> stu1 = Student()
>>> stu1.name = 'John'
>>> stu1.addr = 'Beijing'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Student' object has no attribute 'addr'

  __slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用。

>>> class MidStudent(Student):
... pass
...
>>> stu2 = MidStudent()
>>> stu2.addr = 'Beijing'
>>> print(stu2.addr)
Beijing

  slots只能限制添加属性,不能限制通过添加方法来添加属性。

>>> from types import MethodType
>>>
>>> class School(object):
... __slots__ = ('name')
...
>>> def set_city(self, city):
... self.city = city
...
>>> School.set_city = MethodType(set_city, School)
>>>
>>> sch = School()
>>> sch.set_city('BeiJing')
>>> print(sch.city)
BeiJing

  Python创建class的方法就是使用type()函数。 type()函数既可以返回一个对象的类型,又可以创建出新的类型。

>>> def fun(self, name='World'):
... print('Hello %s' % name)
...
>>> #创建Hello类
... Hello = type('Hello', (object,), dict(hello=fun))
>>>
>>> h = Hello()
>>> h.hello()
Hello World

  要创建一个class对象,type()函数依次传入3个参数:

  1. class的名称。
  2. 继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法。
  3. class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。

  通过type()函数创建的类和直接写class是完全一样的,因为Python解释器遇到class定义时,仅仅是扫描一下class定义的语法,然后调用type()函数创建出class。

python动态绑定属性和方法的更多相关文章

  1. python 类属性与方法

    Python 类属性与方法 标签(空格分隔): Python Python的访问限制 Python支持面向对象,其对属性的权限控制通过属性名来实现,如果一个属性有双下划线开头(__),该属性就无法被外 ...

  2. Python 给实例或者类动态绑定属性和方法

    首页定义一个class,创建一个实例之后,我们可以给该实例绑定任何属性和方法,先定义class: class Student: def __init__(self, name, score): sel ...

  3. Python动态绑定属性slots的使用

    当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.废话不多说,我们看一个例子: class Person(object): pass ...

  4. Python——特殊属性与方法

    Python 对象 中以双下划线开头和结尾的属性称为特殊属性,由于对象的方法也属于属性,因此以双下划线开头和结尾的方法称为特殊方法.对这些对象执行一些特定的运算时,Python会自动视图调用这些实例的 ...

  5. Python 类属性和方法

    import types class Dog(object): __slots__ = ("name", "color", "info") ...

  6. 菜鸟初识python request属性及方法说明

    if  request.REQUEST.has_key('键值'): HttpRequest对象的属性 参考: 表 H-1. HttpRequest对象的属性 属性 描述 path 表示提交请求页面完 ...

  7. python request属性及方法说明

    if  request.REQUEST.has_key('键值'): HttpRequest对象的属性 参考: 表 H-1. HttpRequest对象的属性 属      性 描述 path 表示提 ...

  8. 转:python request属性及方法说明

    转:http://blog.csdn.net/u013398398/article/details/52214582 if  request.REQUEST.has_key('键值'): HttpRe ...

  9. Python复数属性和方法操作实例

    转自: https://blog.csdn.net/henni_719/article/details/56665254 #coding=utf8 ''' 复数是由一个实数和一个虚数组合构成,表示为: ...

随机推荐

  1. maven settings.xml配置优化

    <?xml version="1.0" encoding="UTF-8"?> <settings> <localRepositor ...

  2. linux配置防火墙

    centos6.5 防火墙开放80端口 iptables -I INPUT -p tcp –dport 80 -j ACCEPT //注意,dport前面是两个-,其中-I是指在防火墙INPUT表最前 ...

  3. laravel使用过程中一些总结

    推荐连接: laravel辅助函数总结:https://laravel-china.org/docs/laravel/5.5/helpers 基于 Laravel 集成的 Monolog 库对日志进行 ...

  4. 怎样解题 (G. 波利亚 著)

    第一部分 (已看) 目的 1. 帮助学生 2. 问题,建议,思维活动 3. 普遍性 4. 常识 5. 教师和学生,模仿和实践 主要部分,主要问题 6. 四个阶段 7. 理解题目 8. 例子 9. 拟订 ...

  5. yield return:使用.NET的状态机生成器

    通过关键字词组yield return,.Net Framework(从2.0开始)会为我们生成一个状态机.状态机实际上就是一个可枚举的类型化集合 理解yield return的工作方式 关键字词组y ...

  6. egret学习

    1.egret wing4.0不能创建egret游戏项目, 重置了引擎之后就可以了 2.入门介绍:http://developer.egret.com/cn/github/egret-docs/Eng ...

  7. css动画和js动画的差异

    代码复杂度,js 动画代码相对复杂一些 动画运行时,对动画的控制程度上,js 能够让动画,暂停,取消,终止,css动画不能添加事件 动画性能看,js 动画多了一个js 解析的过程,性能不如 css 动 ...

  8. 枚举 Java Enumeration接口

    Enumation 定义了一些方法,通过这些方法可以枚举对象集合中的元素 如: boolean hasMoreElements() 测试此枚举是否包含更多的元素 object nextElement( ...

  9. openstack--5--控制节点和计算节点安装配置nova

    Nova相关介绍 目前的Nova主要由API,Compute,Conductor,Scheduler组成 Compute:用来交互并管理虚拟机的生命周期: Scheduler:从可用池中根据各种策略选 ...

  10. LambdaAOP

    项目地址 :  https://github.com/kelin-xycs/LambdaAOP LambdaAOP 一个 用 C# 实现的 使用 Lambda 表达式 的 AOP 这是 一个 用 C# ...