关于动态语言Python的讨论

master
Qi38ngf4a 5 years ago
parent 0e5d6f2799
commit 58f034278b

@ -0,0 +1,113 @@
##什么是动态语言?
Dynamic Programming Language (动态语言或动态编程语言) 动态语言准确地说是指程序在运行时可以改变其结构新的函数可以被引进已有的函数可以被删除等在结构上的变化。比如众所周知的ECMAScript(JavaScript)便是一个动态语言。除此之外如Ruby、Python等也都属于动态语言而C、C++等语言则不属于动态语言。
为什么说Python是一门动态语言
看下面这个例子:
def choose_class(name):
    if name == 'foo':
        class Foo(object):
            pass
        return Foo     # 返回的是类,不是类的实例
    else:
        class Bar(object):
            pass
        return Bar
不难看出Python是可以实现动态类的创建类在任意代码位置符合正确的书写格式或者给类增加删除属性。因为类也是对象你可以在运行时动态的创建它们就像其他任何对象一样。你可以在函数中创建类使用class关键字即可。
可能你觉得还不够动态因为你仍然需要自己编写整个类的代码。由于类也是对象所以它们必须是通过什么东西来生成的才对。当你使用class关键字时Python解释器自动创建这个对象。但就和Python中的大多数事情一样Python仍然提供给你手动处理的方法。内建函数中有一个名叫type的内建函数这个内建函数古老但强大的函数 它能够让你知道一个对象的类型是什么就像这样
 
>>> MyShinyClass = type('MyShinyClass', (), {})  # 返回一个类对象
>>> print MyShinyClass<class '__main__.MyShinyClass'
>>>> print MyShinyClass()  #  创建一个该类的实例
<__main__.MyShinyClass object at 0x8997cec>另附type使用方法
#type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
##如何动态添加属性?
 ###2.1 添加对象属性
class Obj(object):
def __init__(self):
self.name = '张亚飞'
obj = Obj()
obj.age = 23
print(obj.age)
obj2 = Obj()
print(obj2.age)
由以上代码可知Obj类有两个属性name和age。通过[对象名.属性名]给类对象obj动态添加了对象属性addr而Obj的另一个类对象obj2却不能调用这个属性。
注:通过对象名添加的对象属性,只有这个对象能使用
###2.2 添加类属性
Obj.score = 100
print(obj.score)
print(obj2.score)
 由以上代码可知,通过[类名.属性名]给类Obj动态添加了类属性addrObj的类对象obj和obj2都能调用这个属性
    注:通过类名添加的类属性,这个类的所有对象都能使用
 
##如何动态添加方法?
类中有三种方法,实例方法,静态方法和类方法,三种方法的区别如下:
实例方法需要绑定要一个对象上第一个参数默认使用self会把对象作为第一个参数传递进来
静态方法:使用装饰器@staticmethod进行定义类和对象都可以调用不需要默认参数
类方法:使用装饰器@classmethod进行定义类和对象都可以调用第一个参数默认使用cls会把类作为第一个参数传递进来
from types import MethodType
class Obj(object):
# __slots__ = ('name', 'age')
def __init__(self):
self.name = '张亚飞'
def set_score(self, score):
self.score = score
@staticmethod
def static_func():
print('static_func')
@classmethod
def class_func(cls):
print('class_method')
类中有三种方法,实例方法,静态方法和类方法,三种方法的区别如下:
实例方法需要绑定要一个对象上第一个参数默认使用self会把对象作为第一个参数传递进来
静态方法:使用装饰器@staticmethod进行定义类和对象都可以调用不需要默认参数
类方法:使用装饰器@classmethod进行定义类和对象都可以调用第一个参数默认使用cls会把类作为第一个参数传递进来
# 动态添加实例方法
obj = Obj()
obj.set_score = MethodType(set_score, obj)
obj.set_score(99)
print(obj.score) # 99
obj2.set_score(99) # AttributeError: 'Obj' object has no attribute 'set_score'
由以上代码可知Obj类有一个方法eat()方法。通过[types.MethodType(方法名, 对象名)]给类对象zhangsan动态添加了对象方法run()同理Obj的另一个类对象lisi不能调用这个方法
注:通过对象名添加的对象方法,只有这个对象能使用
# 添加静态方法
Obj.static_func = static_func
Obj.static_func()
obj.static_func()
obj2.static_func()
由以上代码可知,通过[类名.静态方法名]给类Obj动态添加了静态方法static_func()Obj类的Obj对象和obj2对象都能调用这个方法
注:通过类名添加的静态方法,这个类及这个类的所有对象都能使用
# 添加类方法
Obj.class_func = class_func
Obj.class_func()
obj.class_func()
obj2.class_func()
由以上代码可知,通过[类名.类方法名]给类Obj动态添加了类方法class_func()Obj类的obj对象和obj2对象都能调用这个方法
注:通过类名添加的类方法,这个类及这个类的所有对象都能使用
##__slots__的使用
  通过以上内容我们知道如何动态的添加属性和方法。但是如果我们想要限制class的属性该怎么办例如只允许Obj实例添加name和age属性。为了达到这个目的Python允许在定义class的时候定义一个特殊变量__slots__来限制该class能添加的属性。
class Obj(object):
__slots__ = ('name', 'age')
obj = Obj()
obj.name = 'zhangyafei'
obj.age = 23
obj.score = 99 # AttributeError: 'Obj' object has no attribute 'score'
Obj.score = 100
print(obj.score) # 100
obj.score = 99 # AttributeError: 'Obj' object attribute 'score' is read-only
通过以上代码可知__slots__对Obj类的动态添加没有限制而Obj类对象obj不能再动态添加对象属性和方法。
对于__slot__有以下几个需要注意的地方
__slots__只对类对象进行限制不对类进行限制
__slots__不仅限制类对象的属性还限制类对象的方法
__slots__仅对当前类起作用对继承的子类不起作用
在子类中定义__slots__子类允许定义的属性就是自身的__slots__加上父类的__slots__
 
Loading…
Cancel
Save