类 创建
class D : def __init__ (self) : print(slef)
实例化(创建对象)
class B : def __init__ (self, a, b, c, d) : print(a) print(b) print(c) print(d) b = B(1 ,2 ,3 ,4 )
创建对象使用 类名(init 函数除第一个参数外的参数列表)
创建对象的时候 实际执行了 init 函数
首先创建对象
对象作为self参数传递给__init__
函数
返回self
class Door : def __init__ (self, number, status) : self.number = number self.status = status def open (self) : self.status = 'openning' def close (self) : self.status = 'closed' door = Door(8 , 'closed' ) door.open() print(door.status)
作用域
class E : NAME = 'E' def __init__ (self,name) : self.name = name e = E('e' ) print(e.NAME) print(E.NAME) e2 = E('e2' ) print(e2.NAME) E.NAME = 'new NAME' print(e.NAME) e.status = 0 print(e.status)
类变量对类和实例都可见
所有实例共享类变量
Python 可动态的给对象增减属性
当给实例的类变量赋值时,相当于动态的给这个实例增加 了一个属性,覆盖 了类变量
类装饰器 def set_name (cls, name) : cls.NAME = name return cls class F : pass F1 = set_name(F, 'F' ) f1 = F1() print(F1.NAME) print(f1.NAME) def set_name (name) : def warp (cls) : cls.NAME = name return cls return warp @set_name('G') class G : pass print(G.NAME)
def print_name (cls) : def get_name (self) : return cls.__name__ cls.__get_name__ = get_name return cls @print_name class H : pass h = H() print(h.__get_name__())
类装饰器通常用于给类增加属性
方法都是类级类方法、静态方法 方法的定义都是类级的,但是有的方法使用实例调用,有的方法使用类来调用
##### selfclass I : def print (self) : print('instance method' ) @classmethod # 当一个方法,被classmethod装饰的时候,第一个参数变成类本身,这样的方法叫类方法 def class_print (cls) : print(id(cls)) print('class method' ) @staticmethod # 当一个方法被stasticmethod装饰的时候,不会自动传递第一个参数,这样的方法叫做静态方法 def static_method () : print('static method' ) def xxx_print () : print('this is a function' ) i =I() print(i.print()) print(I.print())
当一个方法,被classmethod装饰的时候,第一个参数变成类本身,这样的方法叫类方法
当一个方法被stasticmethod装饰的时候,不会自动传递第一个参数,这样的方法叫做静态方法
实例调用实例方法时会自动传入self参数, self为实例本身 I.print(i)
实例方法只能由实例调用类方法
class I: def print(self): print('instance method') @classmethod # 当一个方法,被classmethod装饰的时候,第一个参数变成类本身,这样的方法叫类方法 def class_print(cls): print(id(cls)) print('class method') @staticmethod # 当一个方法被stasticmethod装饰的时候,不会自动传递第一个参数,这样的方法叫做静态方法 def static_method(): print('static method') def xxx_print(): print('this is a function') I.class_print() # 返回 6010184 class method print(id(I)) # 返回 6993224 i =I() i.class_print() # 类方法可以被实例使用,并且被实例使用时,传入的第一个参数还是类 返回 6993224 class method I.static_method() # 返回 -> static method print(i.static_method()) # 返回 -> static method print(I.xxx_print()) # 返回 ->this is a function print(i.xxx_print()) # TypeError 报错
访问控制(私有属性 方法) class Door : def __init__ (self, number, status) : self.number = number self.__status = status def open (self) : self.__status = 'opening' def close (self) : self.__status = 'closed' def status (self) : return self.__status def __set_number (self, number) : self.number = number door =Door(8 , 'closed' ) door.__status print(door.__status) print(door.status()) print(door.open())
所有双下划线开始,非双下划线结尾 的成员,都是私有成员
class Door : def __init__ (self, number, status) : self.number = number self.__status = status def open (self) : self.__status = 'opening' def close (self) : self.__status = 'closed' def status (self) : return self.__status def __set_number (self, number) : self.number = number door =Door(8 , 'closed' ) print(door._Door__status) door._Door__status = 'opennning' print(door.status())
_类名 + 带双下划线的属性
Python的私有成员是通过改名实现的
严格的说, Python里没有真正私有成员除非真的有必要,并且清除明白的知道会有什么后果,否则不要用这个黑魔法 90%的程序员有生之年用不到
私有方法定义 是一种惯用法, 标记此成员为私有, 但是解释器不不做任何处理
class Door : def __init__ (self, number, status) : self.xxx = 3 self.__number = number self.__status = status def open (self) : self.__status = 'opening' def close (self) : self.__status = 'closed' @property # property 装饰器会把一个仅有self参数的函数,变成一个属性, 属性的值,为方法的返回值 def status (self) : return self.__status def __set_number (self, number) : self.__number = number number = property(lambda self: self.__number, lambda self, value: self.__number = value, lambda self: print('cant remove number property' ))
类的继承 class Base : def base_print (self) : print('base' ) class A (Base) : def a_print (self) : print('a' ) a = A() print(a.a_print()) print(a.base_print())
class Base : PUBLIC_CALSS_VAR = 'PUBLIC_CLASS_VAR' __PRIVATE_CLASS_VAR = 'PRIVATE_CLASS_VAR' def __init__ (self) : self.public_instance_var = 'public_instance_var' self.__private_instance_var = 'private__instance_var' @classmethod def public_class_name (cls) : return 'public_class_method' @classmethod def __private_classmethod (cls) : return 'private_classmethod' @staticmethod def public_static_method () : return 'public static method' @staticmethod def __private_static_method () : return 'private static method' def public_instance_method (self) : return 'public_instance_method' def __private_instance_method (self) : return 'private_instance_method' class Sub (Base) : def print (self) : print(self.PUBLIC_CALSS_VAR) sub = Sub() print(sub.print()) class Sub2 (Base) : def print (self) : print(self.__PRIVATE_CLASS_VAR) sub2 = Sub2() print(sub2.print()) class Sub3 (Base) : def print (self) : print(self.public_instance_var) sub3 =Sub3() print(sub3.print())
凡是公有的都能继承
凡是私有的都不能继承
原来是什么,继承过来还是什么
方法重写 class Base : def __init__ (self) : self.__a = 4 def print (self) : print('Base.print' ) @classmethod def cls_print (cls) : print('Base.cls_print' ) class Sub (Base) : def print (self) : print('Sub.print' ) sub = Sub() print(sub.print())
当子类和父类有同名成员的时候, 子类的成员会覆盖父类的同名成员
class Base : NAME = 'BASE' class Sub (Base) : NAME = 'SUB' def print (self) : print(self.NAME) print(super(Sub, Sub).NAME) print(Base.NAME) Sub().print() SUB BASE
super 对象只能获取类的属性
多继承 class Base : pass class Sub (Base) : pass class Base2 : pass class Sub2 (Base, Base2) : pass
应该尽量避免多继承
多继承会对程序的心智负担造成非常大的压力
Python是解释执行的,一段代码只有执行到的时候,才知道有没有错
多继承是一剂毒药
类装饰器
设置一些类变量
可以给类增加一些方法
Mixin