你可以定义一个由自己想要功能的函数,以下是简单的规则:
#Python 定义函数使用 def 关键字,一般格式如下:
def 函数名(参数列表):
函数体
#更复杂点的应用,函数中带上参数变量:
def max(a, b):
if a > b:
return a
else:
return b
a = 4
b = 5
print(max(a, b))
def print_xing():
print("***************************")
def print_text():
print("这是一个函数调用实例!")
print_xing()
print_text()
print_xing()
#运行结果
***************************
这是一个函数调用实例!
***************************
def max(a,b):
if a>b:
return a
else:
return b
x=int(input("请输入一个数x:"))
y=int(input("请再输入一个数y:"))
z=max(x,y)
print("较大数为:",z)
分析这个比较最大数,其中max()函数括号内的a,b就是该函数的形参;而在调用函数时,括号内的x和y则是传递给该函数的实参。
必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
调用 print_text()函数,你必须传入一个参数,不然会出现语法错误:
def print_text(x,y):
print(x,y)
print_text("hello","Final Exam!")
print_text("hello")
#运行结果
hello Final Exam!
Traceback (most recent call last):
File "D:/pycharm/py代码/Python期末/函数调用.py", line 26, in <module>
print_text("hello")
TypeError: print_text() missing 1 required positional argument: 'y'
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
以下实例在函数 fun() 调用时使用参数名:
def fun(discount,price):
print("商品折扣:",discount)
print("商品价格:",price)
return
fun(price=100,discount=0.4)
#运行结果
商品折扣: 0.4
商品价格: 100
调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 price 参数,则使用默认值:
def fun(discount,price=100):
print("商品折扣:",discount)
print("商品价格:",price)
return
fun(0.4)
#运行结果
商品折扣: 0.4
商品价格: 100
**值得注意的是,在定义默认值参数的函数时,只能将默认值赋给最右端的参数,否则会出现语法错误。**在Pycharm中早已经出现报错了。
def fun(discount=0.4,price):
print("商品折扣:",discount)
print("商品价格:",price)
return
fun(100)
#运行结果
def fun(discount=0.4,price):
^
SyntaxError: non-default argument follows default argument
你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。只需在参数列表最右侧增加一个带*的参数,基本语法格式如下:
def 函数名([形参列表] *args):
函数体
#例子
def f(x,y,*args):
print(x)
print(y)
print(args)
f(10,9,8,7,6,5,4,3,2,1)
#运行结果
10
9
(8, 7, 6, 5, 4, 3, 2, 1)
return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的 return 语句返回 None。可以返回0个、1个或一组值,以下实例演示了 return 语句的用法:
def fun(discount,price):
price=discount*price
print("商品折扣:",discount)
print("商品价格:",price)
return price
fun(0.5,100)
#运行结果
商品折扣: 0.5
商品价格: 50.0
所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
函数名=lambda[参数列表] : 表达式
sum=lambda arg1,arg2:arg1+arg2;
print("total:",sum(20,50))
#运行结果
total: 70
对象
现实世界中客观存在的事物称作对象,任何对象都具有各自的特征(属性)和行为(方法)。**对象的特征用数据来表示,称为属性;对象的行为用程序代码实现,称为对象的方法。**总之,任何对象都是由属性和方法组成的。
类
类是具有相同属性和行为的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述。任何对象都是某个类的实例。
用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
消息
一个系统由若干个对象组成,各个对象之间通过消息相互联系,相互作用。消息是一个对象要求另一个对象实施某项操作的请求。发送者发送消息,在一条消息中,需要包含消息的接收者和要求接收者执行某项操作的请求,接收者通过调用相应的方法响应消息,这个过程被不断的重复,从而驱动整个程序的运行。
封装
封装是指把对象的数据(属性)和操作数据的过程(方法)结合在一起,构成独立的单元,它的内部信息对外界是隐蔽的,不允许外界直接存取对象的属性,只能通过类提供的外部接口与对该对象实施各项操作,保证了程序中数据的安全性。
类是数据封装的工具,对象是封装的实现。
继承
继承反映的是类与类直接抽象级别的不同,根据继承与被继承的关系,可分为基类和衍类,基类也称为父类,衍类也称为子类,正如"继承"这个词的字面含义一样,子类将从父类那里获得所有的属性和方法,并且可以对这些获得的属性和方法进行改造,使之具有自己的特点。
多态
多态是指统一名字方法产生了多种不同的动作行为,也就是不同的对象收到相同的消息时产生不同的行为方式。该多态的概念应用于面向对象程序设计,增强了程序对客观世界的模拟性,使得对象程序具有更好的可读性。
定义类
在python中,用class关键字来定义类,定义类的语法格式如下:
class ClassName:
<statement-1>
.
.
.
<statement-N>
#应用示例
class CC:
x=10
y=20
z=30
def show(self):
print((self.x+self.y+self.z)/3)
b=CC()
b.x=30
b.show()
#运行结果
26.666666666666668
对象的创建和使用
在Python中,用赋值的方式创建类的实例,一般格式为:
对象名=类名(参数列表)
创建对象后,可以使用“.”运算符,通过实例来防卫这个类的属性和方法(函数)。实例如上。
类属性和实例属性
类属性
类属性为所有类对象的实例对象所共有。类属性通常在类体中初始化。对于公有的类属性,在类外可以通过类对象和实例对象访问。
类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
class Person:
name='brenden'
__age=18
p=Person()
print(p.name)
print(Person.name)
print(p.__age)#报错,不能在类外通过实例对象访问私有的类属性
print(Person._age)#报错,不能在类外通过类对象访问私有的类属性
实例属性
实例属性不需要在类中显示定义,而应该在_ _ init _ _ 构造函数中定义,定义时以"self."作为前缀,实例属性属于特定的实例。所有的实例属性最好在 _ _ init _ _ 中给出。实例属性在内部通过“self.”访问,在外部通过对象实例访问。
class Student:
def __init__(self,name,age,grade):
self.name=name
self.age=age
self.grade=grade
def say_hi(self):
print('I am a student ,my name is ' ,self.name)
s1=Student('王子',21,3)
s1.say_hi()
print(s1.grade)
s2=Student('公主',20,2)
s2.say_hi()
print(s2.grade)
#运行结果
I am a student ,my name is 王子
3
I am a student ,my name is 公主
2
上述例子中,Student类中定义了实例属性name,age和grade。s1、s2是Student的两个实例,这两个实例分别拥有自己的属性值,有别于其他对象。实例的属性可以向其他变量一样进行操作。
s1.grade=s1.grade+1
类的方法
方法是与类相关的函数。方法和函数不同,函数时封装操作的小程序。方法是定义在类内部的函数,并且定义方法与普通函数有所不同。类的方法主要有三种类型:实例方法、类方法和静态方法,不同的方法有不用的使用场景和声明调用形式,不同的方法也具有不同的访问限制。实例方法是属于实例的方法,通过实例名方法名调用,该方法可以访问类属性、实例属性、类方法、实例方法和静态方法。类方法是属于类的方法,可以通过实例名方法名,也可以通过类名方法名调用。类方法不能访问实例属性和实例方法。静态方法是与类实例对象无关的方法,调用形式同类方法类似。
方法的声明和调用
在类的内部,使用def关键字可以为类定义一个方法。与一般函数定义不同,类方法必须包含对象本身的参数,通常为self,且为第一个参数。声明方法的语法格式如下:
def 方法名(self,[形参列表])
函数体
方法调用的语法格式如下:
对象.方法名([参数列表])
在调用方法时,第一个参数self不需要用户为其赋值,Python自动把对象实例传递给参数self。
实例方法
实例方法是在类中经常定义的成员方法,它至少有一个参数并且必须以实例对象作为其第一个参数,一般以“self”作为第一个参数。在类外,实例方法只能通过实例对象去调用。
#定义Person类,通过实例调用实例方法
class Person:
place = 'jiangxijxau'
def getPlace(self):#实例方法
return self.place
p=Person()
print(p.getPlace())
print(p.place)
#运行结果
jiangxijxau
jiangxijxau
类方法
类方法不对特定实例进行操作,在类方法中访问实例属性会导致错误。类方法需要用修饰器"@ classmethod"来标识其为类方法。对于类方法,第一个参数必须是类对象,一般以“cls”作为第一个参数,类方法可以通过实例对象和类对象进行访问。
类方法还有一个用途就是可以对类属性进行修改。
#定义Person类,定义并调用类方法
class Person:
place = 'jiangxijxau'
@classmethod
def getPlace(cls):
return cls.place
p=Person()
print(p.getPlace())
print(Person.getPlace())
#运行结果
jiangxijxau
jiangxijxau
#定义Person类,定义并修改类属性
class Person:
place = 'jiangxijxau'
@classmethod
def getPlace(cls):
return cls.place
@classmethod
def setPlace(cls,place1):
cls.place=place1
p=Person()
p.setPlace("shanghai")
print(p.getPlace())
print(Person.getPlace())
#运行结果
shanghai
shanghai
静态方法
静态方法需要通过修饰器“@staticmethod”来进行修饰,静态方法不需要多定义参数。
#定义Person类,定义并调用静态方法
class Person:
place='jishui'
@staticmethod
def getPlace():
return Person.place
print(Person.getPlace())
#运行结果
jishui
构造方法
构造方法 _ _ init _ _ (self,…)在生成对象是调用,可以用来进行一些属性初始化操作,不需要显式去调用,系统会默认执行。构造方法支持重载,如果用户自己没有重新定义构造方法,系统就自动执行默认的构造方法。
#构造方法并使用示例
class Person:
def __init__(self,name):
self.PersonName=name
def sayHi(self):
print('大家好,我是{}。'.format(self.PersonName))
p=Person('泽冷')
p.sayHi()
#运行结果
大家好,我是泽冷。
析构方法
析构方法 _ _ def _ _ (self) 在释放对象时被调用,支持重载,可以在其中进行一些释放资源的操作,不需要显式去调用
#构造方法并使用示例
class Test:
def __init__(self):
print('构造方法')
def __del__(self):
print("析构方法")
def myf(self):
print('调用自定义方法')
obj = Test()
obj.myf()
del obj
#运行结果
构造方法
调用自定义方法
析构方法
属性的访问控制
python中没有像C++中public和private这些关键字来区别公有属性和私有属性,它是以属性命名的方式来区别的,如果在属性名前面加了两个下划线 _ _ ,那么表示私有属性,否则为公有属性。如果在方法名前面加了则说明是私有方法。
方法的访问控制
在类中可以根据需要定义一些方法,定义方法采用def关键字,在类中定义的方法至少会有一个参数,一般以名为“self”的变量作为该参数,而且需要作为第一个参数。
继承用于指定一个类将从其父类获取其大部分或全部功能。用户对现有类进行修改,来创建一个新的类,称为子类或派生类,原有类称为父类或基类。
#面向对象之继承
class Person(object):
def __init__(self,name,gender):
self.name=name
self.gender=gender
print('person类 __ini()__.','姓名:',self.name)
class Student(Person):
def __init__(self,name,gender,score):
super(Student, self).__init__(name,gender)
self.score=score
print('Student类 __ini()__.','姓名:',self.name)
#“__main__”等于当前执行文件的名称
if __name__=="__main__":
person=Person('张三','男')
student=Student("李四",'女',100)
#运行结果
person类 __ini()__. 姓名: 张三
person类 __ini()__. 姓名: 李四
Student类 __ini()__. 姓名: 李四
#面向对象之多重继承
class P1():
def foo(self):
print("p1-foo")
class P2():
def foo(self):
print("P2-foo")
def bar(self):
print("P2-bar")
class C1(P1,P2):
pass
class C2(P1,P2):
def bar(self):
print("C2-bar")
class D(C1,C2):
pass
if __name__=='__main__':
d=D()
d.foo()
d.bar()
#运行结果
p1-foo
C2-bar
子类可以继承一个父类,也可以继承多个父类,这就是多重继承。多重继承的语法格式如上。
多态即多种形态,在运行时确定其状态,在编译阶段无法确定其类型,这就是多态。
多态性指的是:向不同对象发送同一条消息,不同对象在接收时会产生不同的行为(即方法)。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。
#不使用多态的面向对象程序实现
class ArmyDog(object):
def bite_enemy(self):
print('追击敌人')
class DrugDog(object):
def track_drug(self):
print('追查毒品')
class Person(object):
def work_with_army(self,dog):
dog.bite_enemy()
def work_with_drug(self,dog):
dog.track_drug()
person = Person()
person.work_with_army(ArmyDog())
person.work_with_drug(DrugDog())
#运行结果
追击敌人
追查毒品
#使用多态的面向对象程序实现
class Dog(object):
def work(self):
pass
class ArmyDog(Dog):
def work(self):
print("追击敌人")
class DrugDog(Dog):
def work(self):
print("追查毒品")
class Person(object):
def work_with_dog(self,dog):
dog.work()
person = Person()
person.work_with_dog(ArmyDog())
person.work_with_dog(DrugDog())
#运行结果
追击敌人
追查毒品
封装其实分为两个层面,第一个层面的封装:创建类和对象会分别创建两者的名称空间,只能用“类名.”或者“实例名.”的方式去访问里面的属性和方法,这就是一种封装。
第二个层面的封装:类中把某些属性和方法隐藏起来(或者说定义成私有的),只在类的内部使用,外部无法访问,或者留下少量接口(函数)供外部访问。在继承中,如果父类不想让子类覆盖自己的方法,可以将方法定义为私有的。
class A:
def fm(self):
print('from A')
def test(self):
self.fm()
class B(A):
def fm(self):
print('from B')
b=B()
b.test()
#运行结果#运行结果
from B
#将fm()定义成私有的,即 _ _ fm (),输出结果就会变成“from A”
class A:
def __fm(self):
print('from A')
def test(self):
self.__fm()
class B(A):
def __fm(self):
print('from B')
b=B()
b.test()
#运行结果#运行结果
from A
在某些系统中,为了节省内存资源、保证数据内容的一致性,对某些类要求只能创建一个实例,这就是所谓的单例模式。
单例模式是一种常用的软件设计模式,该模式的主要目的是确保对某一个类还有一个实例存在。
在计算机系统中,还有windows的回收站、操作系统的文件夹系统、应用程序的日志对象、数据库的连接池、网站的计数器、web应用的配置对象、应用程序中的对话框、系统中的缓存等常常被设计成单例。
#创建一个全局唯一的实例对象
class Earth(object):
__instance = None #定义一个类属性做判断
def __new__(cls):
if cls.__instance == None:
#如果__instance为空证明是第一次创建实例
#通过父类的__new__(cls)创建实例
cls.__instance=object.__new__(cls)
return cls.__instance
else:
#返回上一个对象的引用
return cls.__instance
a=Earth()
print(id(a))
b=Earth()
print(id(b))
#运行结果#运行结果
1846493173704
1846493173704
在Python中,一个类创建实例是通过调用父类object的 _ _ new _ _ (cls)方法来创建的。我们可以通过重写 _ _ new _ _ (cls)方法去实现类只创建一个实例。