Python自动化之面向对象进阶

1 静态方法

静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法。

class Dog(object):
    def __init__(self, name):
        self.name = name

    @staticmethod  # 把eat方法变为静态方法
    def eat(self):
        print("%s is eating" % self.name)


d = Dog("ChenRonghua")
d.eat()

运行结果
TypeError: eat() missing 1 required positional argument: 'self'

正确的调用结果

d = Dog("ChenRonghua")
d.eat()  #不能识别类的实例变量

2 类方法

类方法通过@classmethod装饰器实现,类方法和普通方法的区别是, 类方法只能访问类变量,不能访问实例变量。

class Dog(object):
    def __init__(self,name):
        self.name = name
 
    @classmethod
    def eat(self):
        print("%s is eating" % self.name)
 
 
 
d = Dog("ChenRonghua")
d.eat()

运行报错

AttributeError: type object 'Dog' has no attribute 'name'

因为name是实例变量,所以不能访问。

class Dog(object):
	name = "ddddd"
    def __init__(self,name):
        self.name = name

这样就可以正常调用了。

3 属性方法

属性方法的作用就是通过@property把一个方法变成一个静态属性

class Dog(object):
 
    def __init__(self,name):
        self.name = name
 
    @property
    def eat(self):
        print(" %s is eating" %self.name)
 
 
d = Dog("ChenRonghua")
d.eat()

运行报错
TypeError: 'NoneType' object is not callable

d = Dog("ChenRonghua")
d.eat

运行没有错误

ChenRonghua is eating

4 类的特殊成员

1.doc 类的描述信息

class Test():
"""这是类的描述信息"""
pass

a=Test().doc
print(a)

运行结果
这是类的描述信息

2.moduleclass

module 表示当前操作的对象在那个模块

class 表示当前操作的对象的类是什么

3. init 构造方法,通过类创建对象时,自动触发执行。
4.del 析构方法,当对象在内存中被释放时,自动触发执行。
5.call 对象后面加括号,触发执行。

构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

6.dict 查看类或对象中的所有成员
7.str 如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

class Foo(object):
    def __getitem__(self, key):    (1)
        print('__getitem__', key)  (1)

    def __setitem__(self, key, value):    (2)
        print('__setitem__', key, value)  (2)

    def __delitem__(self, key):         (3)
        print('__delitem__', key)		(3)

obj = Foo()

result = obj["k1"]

运行结果

执行(1):getitem k1

obj['k2'] = 'alex'

运行结果

执行(2):setitem k2 alex

__setitem__ k2 alex

运行结果

执行(3):delitem k1

9. new \ metaclass

通过type的方式创建类
def func(self):
print 'hello wupeiqi'

Foo = type('Foo',(object,), {'func': func})
#type第一个参数:类名
#type第二个参数:当前类的基类
#type第三个参数:类的成员

5 类的创建过程和实例化过程

class MyType(type):
 
    def __init__(self, what, bases=None, dict=None):(2)
        print("--MyType init---")
        super(MyType, self).__init__(what, bases, dict)
 
    def __call__(self, *args, **kwargs):   (4)
        print("--MyType call---")
        obj = self.__new__(self, *args, **kwargs)(5)
 
        self.__init__(obj, *args, **kwargs)(7)
 
 
class Foo(object):
 
    __metaclass__ = MyType   (1)
 
    def __init__(self, name):   (8)
        self.name = name
        print("Foo ---init__")
 
    def __new__(cls, *args, **kwargs):(6)
        print("Foo --new--")
        return object.__new__(cls)
 
 
# 第一阶段:解释器从上到下执行代码创建Foo类
# 第二阶段:通过Foo类创建obj对象
obj = Foo("Alex") 	(3)

1.正常情况下,如果没有__metaclass__的话,就会寻找父类,如果父类也没有__metaclass__,就会使用内置的type创建类对象,但是这里是指定了MyType来创建类。
2.(2)创建Foo类 然后到(3)需要Foo类实例化。
3.(4)开始进行实例化的创建。
4.(5)通过__new__实例化出Foo对象,会得到一个Foo的实例对象地址。
5.通过(5)调用了(6)返回一个Foo实例对象地址。
6.(7)进行__init__初始化,调用了(8),到现在Foo()实例化完成。

6 反射 hasattr、getattr、setattr和delattr

hasattr
检查是否含有成员或方法

class Foo(object):
    def __init__(self, name):
        self.name = name

    def eat(self):
        print("%s eating" % self.name )
        return "eat"
obj = Foo("xiaoming")

print(hasattr(obj, "__module__"))
print(hasattr(obj, "name"))

getattr
获取成员的值 getattr(object, name, default=None)

print(getattr(obj, "name","meiyoua"))

如果有就打印name的值,没有就打印meiyoua

setattr

添加成员

setattr(obj,"age","18")

delattr

删除成员

delattr(obj,"name")
print(obj.name)

报错
print(obj.name)
AttributeError: 'Foo' object has no attribute 'name'

posted @ 2016-09-06 17:37  Dus  阅读(345)  评论(0编辑  收藏  举报