面向对象编程进阶

 

静态方法:通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法

 1 #静态方法:只是名义上归类管理,实际在静态方法里访问不了类或实例中的任何属性
 2 class Animal():
 3     def __init__(self,name):
 4         self.name = name
 5     def sleep(self):
 6         print("%s在睡觉"%self.name)
 7 
 8     @staticmethod        #静态方法
 9     def eat(self):       #只是默认是没有参数的 我们写一个self进去
10         print("%s在吃饭"%self.name)
11 
12 
13 
14 a = Animal("柯基")
15 a.sleep()
16 a.eat(a)              #因为设置静态方法 所以在使用时要传对象进去

 

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

 

 1 #类方法只能访问类变量,不能访问实例变量
 2 class Animal():
 3     n = "泰迪"
 4     def __init__(self,name):
 5         self.name = name
 6     def sleep(self):
 7         print("%s在睡觉"%self.name)
 8 
 9     @classmethod        #类方法
10     def eat(self):
11         # print("%s在吃饭"%self.name)   #因为设置类方法所以不能这样调用,要调用类变量
12         print("%s在吃饭" % self.n)
13 
14 
15 
16 a = Animal("柯基")
17 a.sleep()    #柯基在睡觉
18 a.eat()      #泰迪在吃饭

 

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

 1 #属性方法  把一个方法变成一个静态属性
 2 class Animal():
 3     def __init__(self,name):
 4         self.name = name
 5         self.__name= None
 6     def sleep(self):
 7         print("%s在睡觉"%self.name)
 8 
 9     @property        #属性方法
10     def eat(self):
11         print("%s在吃饭"%self.__name)
12 
13     @eat.setter
14     def eat(self,__name):
15         self.__name = __name
16         print(print("%s在吃饭" % self.__name))
17 
18     @eat.deleter
19     def eat(self):
20         del self.__name
21         print("删除成功")
22 
23 
24 a = Animal("柯基")
25 a.sleep()    #柯基在睡觉
26 # a.eat()      #因为将方法变为静态属性了  所以在这边调用要看属性的方式来调用
27 a.eat
28 # a.eat = "金毛"  #这样赋值是不行的 需要用setter 在定义一个一样的方法
29 a.eat = "金毛"    #金毛在吃饭

类的特殊成员方法

 

1. __doc__  表示类的描述信息

1 class Foo:
2     """ 描述类信息,这是用于看片的神奇 """
3  
4     def func(self):
5         pass
6  
7 print Foo.__doc__
8 #输出:类的描述信息

2. __module__ 和  __class__ 

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

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

class C:

    def __init__(self):
        self.name = 'wupeiqi'
from lib.aa import C

obj = C()
print obj.__module__  # 输出 lib.aa,即:输出模块
print obj.__class__      # 输出 lib.aa.C,即:输出类

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

4.__del__

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

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

 

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

 

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

 

class Foo:
 
    def __init__(self):
        pass
     
    def __call__(self, *args, **kwargs):
 
        print '__call__'
 
 
obj = Foo() # 执行 __init__
obj()       # 执行 __call__

 

6. __dict__ 查看类或对象中的所有成员   

 1 class Province:
 2  
 3     country = 'China'
 4  
 5     def __init__(self, name, count):
 6         self.name = name
 7         self.count = count
 8  
 9     def func(self, *args, **kwargs):
10         print 'func'
11  
12 # 获取类的成员,即:静态字段、方法、
13 print Province.__dict__
14 # 输出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}
15  
16 obj1 = Province('HeBei',10000)
17 print obj1.__dict__
18 # 获取 对象obj1 的成员
19 # 输出:{'count': 10000, 'name': 'HeBei'}
20  
21 obj2 = Province('HeNan', 3888)
22 print obj2.__dict__
23 # 获取 对象obj1 的成员
24 # 输出:{'count': 3888, 'name': 'HeNan'}

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

class Foo:
 
    def __str__(self):
        return 'alex li'
 
 
obj = Foo()
print obj
# 输出:alex li
 1 class Animal():
 2     '''这个类是描述对象的'''
 3     def __init__(self,name):
 4         self.name = name
 5     def sleep(self):
 6         print("%s在睡觉"%self.name)
 7     def eat(self):
 8         print("%s在吃饭"%self.name)
 9 
10     def func(self):
11         pass
12 
13     def __call__(self, *args, **kwargs):
14         print("这里是call",args,kwargs)    
15 
16     def __str__(self):
17         return "<obj:%s>" %self.name
18 
19 
20 print (Animal.__doc__)             #这个类是描述对象的
21 a = Animal("柯基")
22 a(123,name=123)                      #这里是call (123,) {'name': 123}
23 print (Animal.__dict__)              #打印类里的所有属性
24 #{'__module__': '__main__', '__doc__': '这个类是描述对象的', '__init__': <function Animal.__init__ at 0x027EEB28>, 'sleep': <function Animal.sleep at 0x027EEAE0>, 'eat': <function Animal.eat at 0x027EEA98>, 'func': <function Animal.func at 0x027EEA50>, '__call__': <function Animal.__call__ at 0x027EEA08>, '__dict__': <attribute '__dict__' of 'Animal' objects>, '__weakref__': <attribute '__weakref__' of 'Animal' objects>}
25 print (a.__dict__)                  #打印所有实例属性,不包括类属性{'name': '柯基'}
26 print(a.__str__())                  #<obj:柯基>

8.__getitem__、__setitem__、__delitem__

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

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']   

9. __new__ \ __metaclass__

 

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

 

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

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

 

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

 

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

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

a). 普通方式 

 
class Foo(object):
  
    def func(self):
        print 'hello alex'

b). 特殊方式

 1 def func(self):
 2     print("hello  %s"%self.name)
 3 
 4 def __init__(self,name,age):
 5     self.name = name
 6     self.age =age
 7 
 8 Foo = type("Foo",(object,),{
 9     "talk":func,
10     "__init__":__init__
11 })
12 
13 f = Foo("大哥","18")
14 f.talk()
15 #type第一个参数:类名
16 #type第二个参数:当前类的基类
17 #type第三个参数:类的成员

So ,孩子记住,类 是由 type 类实例化产生

 

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

 posted on 2018-08-08 23:25  二十二a  阅读(159)  评论(0)    收藏  举报