1. 类名:
1.1 命名方式:class 类名:
1.2 类继承:class 类名(父类):
2. 类变量:
2.1 概念:类变量表示类的属性,在整个实例化的对象中是公用的,定义在类中且在函数体之外,通常不作为实例变量使用,实例化时也被传给对象;
2.2 访问方式:名类.变量名或对象.变量名。
3. 构造函数:
3.1 概念:构造函数是用于初始化类的静态属性,即主要用于定义这个类有哪些静态属性(有什么特点),并定义相关静态属性参数名称,当然还有一些功能你在实例化时就执行,你也可以在这里定义;
3.2 定义方式:用一个特殊方法init(self, 参数) 定义类的属性,在类实例化时该方法会被自动执行(如:自动完成输入的参数值传给对象的各个参数),无需做任何调用操作;
3.2.1 self:是类函数放在第一个位置的必有的一个额外参数, 代表的是类的实例对象,self 不是 python 关键字,我们把他换成 runoob 也是可以正常执行的,只是习惯用self罢了;
3.2.2 实例变量:self.参数:是绑定到一个实例上的变量,在实例化时,可以在参数位输入值,而且无需任何调用就将这些属性值传递给对象,可以覆盖类变量,
3.2.3 访问方式:在类内部用 self.变量名,在类外部用 对象名.变量名
3.2.4 实例变量与类变量的区别,案例详见:ex41c.py
class A(object):
va = 10 # 类变量,它是一个类的全局变量,是所有对象所共享的,它可以被重写(见第19行),在实例化时也重写覆盖(见第11行)
# 在外类外部 类名.类变量 或 对象.类变量 访问,在类内部用 self.类变量 访问
def foo(self):
print (A.va) # 类变量va(A.va)等于10,输出10
print (self.va) # 实例变量av(self.va)在没有被重写前其值就是类变量va(A.va)的值,self.va = A.va = 10(),输出10
self.va = 40 # 重写实例变量va(self.va),它会将类变量va(A.va)覆盖,其实例变量va(self.va)等于40;
# 这里注意,当进行实例时,实例对象的va(self.va)等于覆盖后的值40,但不是真正意义上改类变量va(A.va)等于40,这一点很重要!!
print (A.va) # 类变量va(A.va)还是没变,A.va = 10,输出10
print (self.va) # 实例的变量va(self.va)依然上面一样等于 40,输出40 (见第11行同)
va = 18 # 局部变量va = 18,是方法foo()下的一个局部变量,跟外面的类变量va(A.va)没有任何关系,不是同一个东西!!
print (va) # 输出局部变量 18
A.va = 15 # 重写类变量,类变量va(A.va)由10变成15,是真正意义上把类变量va(A.va)给改写了,就是运行完foo()后,类变量va(A.va)就变成15!!
print (A.va) # 重写后的类变量va(A.va)等于15,输出15,
# 这是注意了,类变量va(A.va)被改后,如没有再次给obj1实例化,那么实例变量va(self.va)还是以前的值 self.va = 40
print (self.va) # 所以,实例变量va(self.va)还是以前的值 self.va = 40,输出40 (与第14行同)
obj1 = A()
obj2 = A()
obj1.foo() #执行结果:10 从内部调用执行
# 10
# 10
# 40
# 18
# 15
# 40
# 注意:在运行完 obj1.foo()方法以后,类变量va(A.va)就该方法由10改成15了;
print (A.va) #执行结果:15 从外部访问类变量va(A.va),执行完foo()函数,类变量va(A.va)已由10改写成15(见19行)
print (obj1.va) #执行结果:40 从外部访问实例对象obj1的变量va(obj1.va),实例变量va(self.va)还是以前的值 self.va = 40,输出40 (与第22行同)
print (obj2.va) #执行结果:15 从外部访问对象obj2的变量va(obj2.va),因为上面运行完一次foo()函数后,类变量va(A.va)由10改写成15(见第19行)
#被改写后,没有再运行foo()函数,所以类变量va(A.va)等于15没变,输出15!
以下是要注意的几点:
因为foo()方法不是构造函数__init__(),所以实例化 obj2 = A() 后,foo()方法并没有被自动执行的;
如果我们把print (obj2.va)代码放到foo()前面去执行,那么它输出的就不是15了,而是修改前的10,不信你可以试试!!
像第47行,这样的类变量尽量避免重写,因为一旦重写后,由这个类所创建的对象将全部被修改,导致各种不料的后果!!
4. 方法
4.1 类的实例方法:
4.1.1 概念:方法用于定义类的实例的动态属性,即用于定义这个类的实例有哪些功能(能干什么),它可以对静态属性做一些操作,也可独自执行一下任务,它必须通过对象被调用后才会被执行,调用方式:对象名.方法;
4.1.2 定义方式:定义在类里,第一个参数是self,是通过的对象的名称进行调用,在实例化时会将该方法传给对象;
4.2 类的方法:
4.2.1 概念:方法用于定义类的动态属性,即用于定义这个类有哪些功能(能干什么),它可以对静态属性做一些操作,也可独自执行一下任务,它必须通过类名调用,调用方式:对象名.方法;
4.2.2 定义方式:定义在类里,参数没有self,通过类名称进行调用,但在实例化时不会将该方法传给对象;
这个两概念一定要搞清楚!!
5. 类的实例化:
5.1 实例化:创建一个类的实例,类的具体对象(如:猫类的“小黑”,狗类的“旺财”,学生类的“张三”),并把类的相关实例属性与方法传递给对象,同时还可以按一定的位置顺序对参数进行赋值。
5.2 访问方式:实例化后,可以 对象名.属性名 的方式进行访问对象属性变量,也可以 对象名.方法 的方式调用对象的方法;
5.3 注意:类的实例方法可以被传给对象,但类的方法不会被传递!
5.4 类的基本构造及实例化的案例:
案例详见:ex41a.py
class people: #定义一个people类
name = 'Human' #定义类变量(全局属性)
na = 'Hu' #定义类公有属性变量
def __init__(self, n , a, w): # 定义类的构造函数,用于初始化类的属性,即用于表述这个类有哪些属性,并定义相关属性参数名称
# 这里的self代表的是类的实例对象,表示这个类的对象也有name,age,weight属性
# 构造函数,一旦被实例化了,就马上自动被执行了,无需任何调用
self.name = n # 定义类的实例变量name,可在参数n位置的传值,可以覆盖类变量,如name
self.age = a # 定义类的实例变量name,可在参数a位置的传值
self.weight = w # 定义类的实例变量name,可在参数w位置的传值
Nw = w-20 # 构造函数中,也可以定义一些功能,一般用于做属性参数的计算,然后再调用它的计算结果
self.Nextyearweight = Nw # 定义类的实例变量Nextyearweight,其值可以通过一定运算后得到
print(f"我后年的目标体重是{self.Nextyearweight}斤!") # 实例化后,这行代码就被自动执行了!
def Nextyear1(d): # 定义一个类的方法(注意:不是实例方法,参数也没有self),可以通过类进行调用,不可以通过实例对象进行调用
Nextw = people.weight - d # 因为是类方法,所以它也只能访问类变量,不能访问实例变量
return Nextw # 返回计算后的结果给调用者
def speak(self, lw): # 定义类的方法(功能函数),即用于表述这个类有什么功能,即它可以静态属性做一些操作,也可以独立实现一些操作
# 功能函数,它只有被实例化后,通过对象以 对象名.方法 方式调用才能执行
print("{}说: 我今年{}岁,体重{}斤哦!".format(self.name, self.age, self.weight)) # 方法speak()可以把按我们要格式把属性打印出来
N_w = self.weight - lw # 方法speak()可以将类的属性及其自己参数做一些运算
print(f"I want to lose weight,next year my weight will be {N_w}!") # 方法speak()可以将运算结果打印出来
print("I can do many thing!!") # 方法speak()可以做一些跟属性没有任何相关的操作
print("We all belong to ",people.name) # 直接调用people类的全局属性name,此时它还没有被覆盖,其值依然是'Human'
print(f"Next year,my weight will be {people.Nextyear1(10)}!") # Nextyear1(10)类普通属性方法,类外部的函数可以通过类进行调用
Weijp = people("Weijp", 39, 144) # 用poeple类实例化(创建)一个具体的对象(一个具体人weijp,这个人有poeple类所有的属性和方法)
# 实例化创建weijp对象后,__init__()马上被自动执行,将传值"Weijp", 39, 144马分别传给对象的参数(n , a, w)
Weijp.speak(10) # 调用对象(weijp这个人)的speak()函数,还给speak()的参数lw赋值10,然后执行该函数
print(f"My name is {Weijp.name}!") # 调用weijp对象的name属性,对象的name属性已被重写,其值是"Weijp"
print(Weijp.na) # 类变量是可以通过对象.属性名 进行访问