创建

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) # 返回 --> E

print(E.NAME) # 返回 --> E

e2 = E('e2')
print(e2.NAME)# 返回 --> E

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) # 返回'F'
print(f1.NAME) # 返回'F'

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__())
  • 类装饰器通常用于给类增加属性
  • 方法都是类级

    类方法、静态方法

    方法的定义都是类级的,但是有的方法使用实例调用,有的方法使用类来调用

##### self

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 =I()
print(i.print()) # 实例调用实例方法时会自动传入self参数, self为实例本身 I.print(i)

print(I.print()) # TypeError 实例方法只能由实例调用

  • 当一个方法,被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 # AttributeError: 'Door' object has no attribute '__status'

print(door.__status) # a new status cloesd

print(door.status()) # closed
print(door.open()) # None
  • 所有双下划线开始,非双下划线结尾的成员,都是私有成员
#coding:utf8

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) # closed
door._Door__status = 'opennning'
print(door.status()) # opennning
  • _类名 + 带双下划线的属性

  • 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

# @property
# def number(self):
# return self.__number

# @number.setter # property setter 装饰器, 可以把一个方法转化为对此赋值,但此方法有一定要求:
# # 1.同名 2.必须接收两个参数 self 和 value, value为所赋的值
# def number(self, number):
# if isinstance(number, int) and number > 0 and number < 10000:
# self.__number = number

# @number.deleter
# def number(self):
# print('cant remove number property')
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()) # a
print(a.base_print()) # base
# 继承一个明显的好处就是可以获取父类的属性和方法
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()) # PUBLIC_CLASS_VAR

# -----------------------------------------------
class Sub2(Base):
def print(self):
print(self.__PRIVATE_CLASS_VAR)

sub2 = Sub2()
print(sub2.print()) # AttributeError: 'Sub2' object has no attribute '_Sub2__PRIVATE_CLASS_VAR'

# -----------------------------------------------
class Sub3(Base):
def print(self):
print(self.public_instance_var)
sub3 =Sub3()
print(sub3.print()) # public_instance_var
  • 凡是公有的都能继承
  • 凡是私有的都不能继承
  • 原来是什么,继承过来还是什么
方法重写
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()) # 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