定义----- def 函数名(形参1,形参2,……): 调用----- 函数名(实参)
(tips:形参指的是—函数完成其工作所需的一项信息;实参指的是调用函数时传递给函数的信息)
按位置赋值----- 调用时,函数名(实参1,实参2,……)实参和形参按位置一一对应
按关键字赋值----- 调用时,函数名()
定义类的声明是class 类名:,注意类名的首字母一定要大写。按Java面对对象的逻辑,类中包含构造方法,实例方法和类方法。Python可以与其非常相似有实例方法,静态方法和类方法。类的属性又叫类变量,Python的类的属性主要有类属性,实例属性和局部属性三种。
实例方法------ Python的构造方法也属于实例方法,构造方法最为特殊,它用于初始化类,构造方法默认声明为def init(self,形参1,形参2,…):其中的__init__是构造的方法名(规定,不能更改),self也是必要的,而且也必须放在首位,它是一个指向对象本身的特殊参数,相当于C++/Java里的this,当创建类的对象时必须调用构造方法,而创建好的对象不要调用__init__方法。构造方法主要为了让类初始化,故类所要求的属性即self.属性有时候会多于形参数目,这都是可以的,形参的目的也只是为了给类初始化提供一些用户定义的值。实例方法主要便于类实现各种功能,可以被对象直接调用,其声明形式为:def 方法名(self,形参1, 形参2,……):值得注意的一点是,由于Python不像C++那样子严格,故方法的形参可以是类的对象!实例方法最大的特点就是,它最少也要包含一个 self 参数,用于绑定调用此方法的实例对象(Python 会自动完成绑定)。
类方法----- Python类方法和实例方法相似,它最少也要包含一个参数,只不过类方法中通常将其命名为 cls,Python会自动将类本身绑定给cls参数(注意,绑定的不是类对象)。也就是说,我们在调用类方法时,无需显式为cls参数传参。和self一样cls参数的命名也不是规定的(可以随意命名),只是Python 程序员约定俗称的习惯而已。 和实例方法最大的不同在于,类方法需要使用@classmethod修饰符进行修饰,例如:
class CLanguage: #类构造方法,也属于实例方法 def __init__(self): self.name = "hello" self.add = "python" #下面定义了一个类方法 @classmethod def info(cls): print("正在调用类方法",cls)注意,如果没有 @classmethod,则 Python 解释器会将 fly() 方法认定为实例方法,而不是类方法。类方法推荐使用类名直接调用,当然也可以使用实例对象来调
静态方法----- 静态方法,可以说成是函数,它和函数唯一的区别是,静态方法定义在类这个空间(类命名空间)中,而函数则定义在程序所在的空间(全局命名空间)中。静态方法没有类似 self、cls 这样的特殊参数,因此 Python 解释器不会对它包含的参数做任何类或对象的绑定。也正因为如此,类的静态方法中无法调用任何类属性和类方法。 静态方法需要使用@staticmethod修饰,例如:
class CLanguage: @staticmethod def info(name,add): print(name,add)静态方法的调用,既可以使用类名,也可以使用类对象,例如: #使用类名直接调用静态方法 CLanguage.info(“python”) #使用类对象调用静态方法 clang = CLanguage()或者clang.info(“python”),运行结果都是python。 在实际编程中,几乎不会用到类方法和静态方法,因为我们完全可以使用函数代替它们实现想要的功能,但在一些特殊的场景中(例如工厂模式中),使用类方法和静态方法也是很不错的选择。
类属性----- 类属性的特点是,所有类的实例化对象都同时共享类属性,也就是说,类属性在所有实例化对象中是作为公用资源存在的。类属性的调用方式有2种,既可以使用类名和类的实例化对象直接调用和修改,注意类属性为所有实例化对象共有,故通过类名修改类变量的值,会影响所有的实例化对象。而通过类对象对类变量赋值,其本质将不再是修改类变量的值,而是在给该对象定义新的实例变量(在讲实例变量时会进行详细介绍)。
class Py : # 下面定义了一个类属性word word = "hello python" #使用类名直接调用 print(Py.word) #修改类变量的值 Py.word = "AMD YES" #使用类的对象调用 python=Py() print(python.word)实例属性----- 实例属性指的是在任意类方法内部,以“self.变量名”的方式定义的变量,其特点是只作用于调用方法的对象。另外,实例属性只能通过对象名访问,无法通过类名访问。
class Language : init_lang="I am program language" #类变量 def __init__(self): #实例方法的构造函数 self.now_lang="now I am python" #实例变量 def pass_language(self): #实例方法 self.pass_lang = "I was C/C++" #实例变量,只有调用该函数才有 obj_vary=Language() #创建对象 print(obj_vary.init_lang) #打印1-对象调用类属性 print(obj_vary.now_lang) #打印2-对象调用实例属性 obj_vary.pass_language() #对象调用实例方法新增实例属性 print(obj_vary.pass_lang) #打印3-对象调用实例属性 obj_vary.init_lange="I want to change" #①对象想修改类变量 print(obj_vary.init_lang) #打印4-尝试用对象调用类属性 print(Language.init_lang) #打印5-尝试用类名调用类属性 obj_vary.new_lang="i was Java" #②通过对象添加实例属性 print(obj_vary.new_lang) #打印6-对象调用实例属性 输出结果为: I am program language now I am python I was C/C++ I am program language I am program language i was Java总结:1.实例属性的标志是self,只有对象才能调用实例属性!2.如代码②所示,Python支持为特定的对象添加实例变量。在代码①想利用对象修改类属性,发现打印4的时候并没有修改成功,这是因为Python在执行代码①时,会视作为类添加一个与某个类变量同名的实例变量,而实例变量和类变量同名,编译器只会优先调用类变量,故通过对象是修改不了类变量的。
局部变量----- 局部变量只能用于所在函数中,函数执行完成后,局部变量也会被销毁。形如def display(self): test=1 这函数里面的test就是局部变量。
继承的格式,B类继承了A类的声明为:class B(A):,其中父类又叫超类,继承的类又叫子类,子类具备父类的所有功能,即子类的对象能够调用父类的所有方法。继承类的构造方法的声明为:
def __init__(self,子形参1,子形参2,子形参3,…….): super().__init__(父形参1,父形参2,……)#这里的super()函数是用来初始化父类的属性。现在对子类初始化进行几点说明:
1.在子类里它的构造函数也需要初始化,而且初始化的声明和父类一样,即都是类的构造函数的声明方式,子类初始化的形参不得少于父类的形参,这是因为子类具备父类所有的方法和属性,如下面例子如果换成代码①就会报错,也可以看到Three_and可以直接调用self.a进行求和输出(test.and2())即子类就直接调用了父类的属性和方法,
2.由于子类继承了父类的所有属性和方法,这样子在子类中也就必须先对其父类的属性来一个初始化,故Python提供super()函数和pass来初始化,如果是单继承用super().init(父形参1,父形参2,……)这里的父形参不赋初值,如果赋了初值则会导致子类初始化时只会用那个值,如下面代码②导致输出错误。多继承用pass其无括号和冒号。
3.子类可以对父类的方法进行重写,其声明形式和其他实例函数一样,主要和父类的方法名一样,只不过执行的代码不同,Python会执行子类重写的方法。
4.子类的属性self.init_num没有用形参赋初值,这即呼应类的属性有时候会多于形参数目,也会用另外一个类的对象(也叫实例)来赋值,这些都是为了类初始化的方便。属性是一个对象的话,就可以调用它类的方法,如代码④。
class Two_and(): def __init__(self,a=0,b=0): self.a=a self.b=b def and2(self): print(self.a+self.b) class Init_num(): def __init__(self,num1=0,num2=0): self.n1=num1 self.n2=num2 def display(self): print("if no number,we will show %d"%(self.n1+self.n2)) class Three_and(Two_and): def __init__(self,a=0,b=0,c=0): #①代码如果为def __init__(self,a=0) super().__init__(a,b) #②代码如果为super().__init__(a=0,b=0) self.c=c self.init_num=Init_num() #③添加代码演示方法的重写 # def and2(self): # print(self.a+self.b+self.c) def and3(self): print(self.a+self.b+self.c) test=Three_and(1,2,3) #④添加代码演示调用实例作为属性 # test.init_num.display() test.and2() test.and3() 输出结果为3和6,按①的情况输出会报错,按②的情况输出结果为0和3,按③的情况则会输出6和6,按④情况则会多输出一句if no number,we will show 0。