面向对象编程进阶
静态方法:通过@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 类实例化产生
posted on
浙公网安备 33010602011771号