day15(Alex python)

版权声明:本文为博主原创文章,转载请注明作者和出处。https://blog.csdn.net/xq920831/article/details/82682821

开始今天的学习。

今天学习一些面向对象的进阶内容:

1. 静态方法和类方法

# -*- coding:utf-8 -*-
# Author: Agent Xu

class People(object):
    name = "agentsun"

    def __init__(self,name):
        self.name = name

    def eat(self,food):
        print("%s is eating %s" %(self.name,food))

    @staticmethod   #实际上和类已经没有关系了,cook当做是一个单独的函数,所以不能用参数
    def cook(self):
        print("%s is cooking %s" %(self.name,"牛排"))

    @classmethod  #类方法,只能用类里定义的变量
    def meet(self):
        print("%s is in a meeting" %(self.name))

a = People("agentxu")
a.eat("西瓜")  #agentxu is eating 西瓜

a.cook(a)  #agentxu is cooking 牛排

a.meet() #agentsun is in a meeting

总结:
静态方法——只是名义上归类管理,实际上在静态方法里访问不了类或实例中的任何属性。

类方法——只能访问类变量,不能访问实例变量。

据说实际中用处不多。。。。

2. 属性方法

把一个方法变成静态属性。

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

    @property
    def hunt(self):
        print("hunt the animal %s" %(self.name))

d = Animal("犀牛")
d.hunt   #hunt the animal 犀牛

但是这样有一个很大的问题,不能传参数了。。。。。那怎么办呢

解决方法:再写一个同名的函数

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

    @property
    def hunt(self):
        print("hunt the animal %s" %(self.name))

    @hunt.setter
    def hunt(self,people):
        print("%s hunt the animal %s" %(people,self.name))

d = Animal("犀牛")
d.hunt   #hunt the animal 犀牛

d.hunt = "agentxu" #agentxu hunt the animal 犀牛
d.hunt   #hunt the animal 犀牛

#如果想保存参数的值则应改成下面的模式
class Animal1(object):
    def __init__(self,name):
        self.name = name
        self.people = None

    @property
    def hunt1(self):
        print("%s hunt the animal %s" %(self.people,self.name))

    @hunt1.setter
    def hunt1(self,people):
        print("%s hunt the animal %s" %(people,self.name))
        self.people = people

f = Animal1("犀牛")
f.hunt1   #None hunt the animal 犀牛

f.hunt1 = "agentxu" #agentxu hunt the animal 犀牛
f.hunt1   #agentxu hunt the animal 犀牛

如果想删除参数,加一个模块

@hunt1.deleter
def hunt1(self):
    del self.people
    print("删除完毕")

更多详细的例子参考:https://www.cnblogs.com/alex3714/articles/5213184.html

3. 特殊方法

  • __doc__
class Dog(object):
    '''这个类是用来描述一种动物的'''
    def __init__(self,name):
        self.name = name

#打印类的描述信息
print(Dog.__doc__)  #这个类是用来描述一种动物的
  • __module__ 和  __class__

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

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

from day8.lizi import Animal

obj = Animal()
print(obj.__module__)  #day8.lizi 输出属于哪个模块
print(obj.__class__)   #<class 'day8.lizi.Animal'> 输出属于哪个类
  • __init__ 

构造方法,通过类创建对象时,自动触发执行。

  • __del__

析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的

  • __call__ 

对象后面加括号,触发执行。

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

class Dog(object):
    '''这个类是用来描述一种动物的'''
    def __init__(self,name):
        self.name = name
    def __call__(self, *args, **kwargs):
        print("calling func")

e = Dog("dog")
Dog("dog")()   #calling func
e()  #calling func 

或者带参数的也阔以。。。

class Dog(object):
    '''这个类是用来描述一种动物的'''
    def __init__(self,name):
        self.name = name
    def __call__(self, *args, **kwargs):
        print("calling func ",args,kwargs)

e = Dog("dog")
e(1,2,3,name=666)  #calling func  (1, 2, 3) {'name': 666}
  • __dict__

查看类或对象中的所有成员。

class Dog(object):
    '''这个类是用来描述一种动物的'''
    def __init__(self,name):
        self.name = name
    def __call__(self, *args, **kwargs):
        print("calling func ",args,kwargs)

print(Dog.__dict__)   #打印类里的所有属性,不包括实例属性
#{'__doc__': '这个类是用来描述一种动物的', '__dict__': <attribute '__dict__' of 'Dog' objects>, '__init__':
#<function Dog.__init__ at 0x0000000000BDF2F0>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>, 
#'__call__': <function Dog.__call__ at 0x0000000000BDF378>, '__module__': '__main__'}
e = Dog("dog")
print(e.__dict__)
#{'name': 'dog'}  打印实例里的所有属性,不包括类属性
  • __str__

如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

class Foo:

    def __str__(self):

        return 'alex li'

obj = Foo()

print obj

# 输出:alex li

  • __getitem__、__setitem__、__delitem__

用于索引操作,如字典。以上分别表示获取、设置、删除数据

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

class Foo(object):

    def __getitem__(self, key):

        print('__getitem__',key)

    def __setitem__(self, key, value):

        print('__setitem__',key,value)

    def __delitem__(self, key):

        print('__delitem__',key)

obj = Foo()

result = obj['k1']      # 自动触发执行 __getitem__

obj['k2'= 'alex'   # 自动触发执行 __setitem__

del obj['k1'

  • __new__ \ __metaclass__

1

2

3

4

5

6

7

8

class Foo(object):

    def __init__(self,name):

        self.name = name

= Foo("alex")

上述代码中,obj 是通过 Foo 类实例化的对象,其实,不仅 obj 是一个对象,Foo类本身也是一个对象,因为在Python中一切事物都是对象

如果按照一切事物都是对象的理论:obj对象是通过执行Foo类的构造方法创建,那么Foo类对象应该也是通过执行某个类的 构造方法 创建。

1

2

print type(f) # 输出:<class '__main__.Foo'>     表示,obj 对象由Foo类创建

print type(Foo) # 输出:<type 'type'>              表示,Foo类对象由 type 类创建

所以,f对象是Foo类的一个实例Foo类对象是 type 类的一个实例,即:Foo类对象 是通过type类的构造方法创建。

那么,创建类就可以有两种方式:

a). 普通方式 

1

2

3

4

class Foo(object):

  

    def func(self):

        print 'hello alex'

b). 特殊方式

1

2

3

4

5

6

7

def func(self):

    print 'hello wupeiqi'

  

Foo = type('Foo',(object,), {'func': func})

#type第一个参数:类名

#type第二个参数:当前类的基类

#type第三个参数:类的成员

这里给一个完整的例子:

def func(self):
    print("hello %s"%(self.name))

def __init__(self,name):
    self.name = name

oop = type('oop',(object,),{'talk':func,'__init__':__init__})

f = oop("agentxu")
f.talk()  #hello agentxu

下面引用内容:

 1 class MyType(type):
 2     def __init__(self,*args,**kwargs):
 3 
 4         print("Mytype __init__",*args,**kwargs)
 5 
 6     def __call__(self, *args, **kwargs):
 7         print("Mytype __call__", *args, **kwargs)
 8         obj = self.__new__(self)
 9         print("obj ",obj,*args, **kwargs)
10         print(self)
11         self.__init__(obj,*args, **kwargs)
12         return obj
13 
14     def __new__(cls, *args, **kwargs):
15         print("Mytype __new__",*args,**kwargs)
16         return type.__new__(cls, *args, **kwargs)
17 
18 print('here...')
19 class Foo(object,metaclass=MyType):
20 
21 
22     def __init__(self,name):
23         self.name = name
24 
25         print("Foo __init__")
26 
27     def __new__(cls, *args, **kwargs):
28         print("Foo __new__",cls, *args, **kwargs)
29         return object.__new__(cls)
30 
31 f = Foo("Alex")
32 print("f",f)
33 print("fname",f.name)

 类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__

 metaclass 详解文章:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python 得票最高那个答案写的非常好

这个效果在python2中能看得出来,python3没有什么效果。

4. 反射

    hasattr(obj,name_str) , 判断一个对象obj里是否有对应的name_str字符串的方法
    getattr(obj,name_str), 根据字符串去获取obj对象里的对应的方法的内存地址
    setattr(obj,'y',z), is equivalent to ``x.y = v''
    delattr(x,y)  删除x.y方法

# -*- coding:utf-8 -*-
# Author: Agent Xu

def bulk(self):
    print("%s is yelling..." %(self.name))

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

    def eat(self):
        print("%s is eating..." %(self.name))

d = Dog("xiaohua")
func = input("the action is:").strip()
print(hasattr(d,func))   #判断输入的字符串是否属于类中定义的方法

getattr(d,func)()  #xiaohua is eating...    getattr()返回输入的字符串对应的类中定义的方法的地址

setattr(d,func,bulk)
d.talk(d)  #xiaohua is yelling...   把类之外的函数加入类,并调用

delattr(d,func)  #删除d.func

注:四种方法试验的时候要分开来操作,这样才能直观的看出结果。

5. 异常处理

异常处理的语句为:try:.........except:............


异常
    try :
        code
    except (Error1,Erro2) as e:
        print e

    except Exception :抓住所有错误,不建议用

参考 http://www.cnblogs.com/wupeiqi/articles/5017742.html

猜你喜欢

转载自blog.csdn.net/xq920831/article/details/82682821