基于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. LeetCode - Daily Temperatures

    Given a list of daily temperatures, produce a list that, for each day in the input, tells you how ma ...

  2. 【java编程】格式化字符串

    String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重载形式. form ...

  3. 使用VUE搭建tab标签组件

    Vue2.0 多 Tab切换组件简单封装,满足自己简单的功能,可以直接拿去使用! 首先上效果图: 功能简单介绍: 1.支持tab切换 2.支持tab定位 3.支持tab自动化 仿React多Tab实现 ...

  4. shell-url-decode

    查询每个小时的clk ,然后获取对应的字段 #!/bin/bash urldecode(){ echo -e "$(sed 's/+/ /g;s/%\(..\)/\\x\1/g;')&quo ...

  5. C++中的智能指针、轻量级指针、强弱指针学习笔记

    一.智能指针学习总结 1.一个非const引用无法指向一个临时变量,但是const引用是可以的! 2.C++中的delete和C中的free()类似,delete NULL不会报"doubl ...

  6. Android 工具视频学习笔记_WDS

    1. 由于Android源码过于庞大,SourceInsight会经常卡死,不适合了.适合的是Android Studio, 非常好用.使用手册上有介绍如何安装. 编译安卓的过程说明手册中也有. 3. ...

  7. Java中的权限学习笔记

    1.Java中的权限有两个层次,一个是类这一层,另一个是类成员那一层. 类这一层: public class可以在本包内被访问,也可以在包外被访问.而没有被public修饰的class只能在本包内被调 ...

  8. lapis 项目添加prometheus 监控

      lapis 是基于openresty 扩展的,所以直接将支持prometheus的模块构建进openresty 就可以了 我使用的是nginx-module-vts 模块 环境准备 我已经构建好了 ...

  9. java_main

    Java中用户向系统传递参数的三种基本方式 main方法 在Java中,main()方法是Java应用程序的入口方法,也就是说,程序在运行的时候,第一个执行的方法就是main()方法,这个方法和其他的 ...

  10. MYSQL 中的 int(11) 到底代表什么意思?

    各 INT 类型无符号最大值用单位表示: INT 类型 无符号最大值用单位表示 TINYINT 255 SMALLINT 65535 MEDIUMINT 1677 万 INT 42 亿 BIGINT ...