python(二)基础

自定义函数

# 自定义函数
def 函数名(参数):
	code...
	code...

# 调用函数
函数名(参数)

定长参数

# 函数调用时,如果有位置参数时,位置参数必须在关键字参数(age=20)的前面
def user_info(name,age,gender):
	print(f'名字是{name},年龄是{age},性别是{gender}')

user_info('雄安',age=20,gender='')

# 缺省参数
def user_info(name,age,gender='男'):
	print(f'名字是{name},年龄是{age},性别是{gender}')

user_info('雄安',age=20)
user_info('雄安',age=20,gender='')

不定长参数

  1. 包裹位置传递(args 是一个元组)
    不定长参数也叫可变参数。用于不确定调用时会传递多少个参数(不传参也行)的场景。此时可以用包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递

    注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组,args是元组类型,这就是包裹位置传递。

def user_info(*args):
	print(args)

# ('tom',)
user_info('tom')

# ('tom',18)
user_info('tom',18)
  1. 包裹关键字传递(kwargs 是一个字典)
def user_info(**kwargs):
	print(kwargs)
#{'name':'tom','age':18,'id':110}
user_info(name='tom',age=18,id=110)

综上:以上两种传递,都是一个组包的过程

文档注释

def sum_num1(a,b):
	'''
	求和函数sum_num1
	param a:参数1
	param b:参数2
	return: 返回值
	'''
	return a + b

变量

修改自定义变量

# 错误示范
# 错误示范
# testA 中的 变量a只是局部变量,并不是全局变量
a = 100

def testA():
  # 200
  a = 200
  print(a)
  # 正确做法
  # global关键字声明a是全局变量
  # global a
  # a = 200

def testB():
  # 100
  print(a)


testA()
testB()

交换变量

a,b = 1,2
a,b = b,a

print(a) # 2
print(b) # 1

引用

在python中,值是靠引用来传递的

我们可以用id()来判断两个变量是否为同一个值的引用。我们可以将id值理解为那块内存的地址标识

可变和不可变类型

在这里插入图片描述

a = 1
b = a
print(b) # 1

print(id(a)) # 140708464157520
print(id(b)) # 140708464157520

a = 2
print(b) # 1,说明int类型为不可变类型

列表为可变数据类型
在这里插入图片描述

lambda表达式(匿名函数)

在这里插入图片描述
在这里插入图片描述

lambda的参数形式

在这里插入图片描述
在这里插入图片描述
带判断的lambda
在这里插入图片描述

列表数据按字典key的值排序

x代表排序的数据,也就是每一个字典
在这里插入图片描述

高阶函数

abs() 绝对值
round() 四舍五入
在这里插入图片描述

内置高阶函数

在这里插入图片描述

reduce():累积:指的是运算,并不是乘

在这里插入图片描述
在这里插入图片描述

filter():过滤序列中不符合条件的元素

在这里插入图片描述

定义类

# 类名要满足标识符规则,同时遵循大驼峰命名习惯
class 类名():
	code...

类属性(就是在pojo里定义一个变量)

类属性的优点:

  • 记录的某项数据始终保持一致时。则定义类属性
  • 实例属性要求每个对象为其单独开辟一份内存空间来记录数据,而类属性为全类所共有,仅占一份内存,更加节省内存空间

修改类属性

class Dog:
  tooth = 10

# 10
print(Dog.tooth)

Dog.tooth = 20
# 20
print(Dog.tooth)

类方法

类方法特点:需要用装饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数

类方法使用场景

  • 当方法中需要使用类对象(如访问私有类属性等)时,定义类方法
  • 类方法一般和类属性配合使用
class Dog:
  __tooth = 10

  @classmethod
  def get_tooth(cls):
    return cls.__tooth

meili = Dog()
result = meili.get_tooth()
print(result)

静态方法

静态方法特点

  • 需要通过装饰器@staticmethod来进行修饰,静态方法既不需要传递类对象也不需要传递实例对象(形参没有self/cls)
  • 静态方法也能够通过实例对象和类对象去访问

静态方法使用场景

  • 当方法中既不需要使用实例对象(如实例对象,实例属性),也不需要使用类对象(如类属性、类方法、创建实例等)时,定义静态方法
  • 取消不需要的参数传递,有利于减少不必要的内存占用和性能消耗
class Dog:
  @staticmethod
  def info_print():
    print('===')

wangcai = Dog()
# ===
wangcai.info_print()
# ===
Dog.info_print()

self(相当于java的this,谁调用就是谁)

self指的是调用该函数的对象

class Washer():

	def wash(self):
		print('洗衣服')
		print(type(self) )

washer = Washer()
# 洗衣服
# <class '__main__.Washer'>
washer.wash()
class Washer():

  # 类属性
  width = 100
  height = 500

  def print_info(self):
    print(self.width)
    print(self.height)

washer = Washer()
# 100 500
washer.print_info()

washer.width = 200
washer.height = 1000
# 200 1000
washer.print_info()

魔法方法(具有特殊功能的函数)

init()作用:初始化对象

注意
该方法在创建对象时默认被调用,不需要手动调用

该方法中的self参数,不需要开发者传递,python解释器会自动把当前的对象引用传递过去

class Washer():

  def __init__(self):
    self.width = 500
    self.height = 800

  def print_info(self):
    print(f'宽是{self.width},高是{self.height}')

washer = Washer()
# 宽是500,高是800
washer.print_info()

带参数的_init_(),和java的构造函数类似

class Washer():

  def __init__(self,width,height):
    self.width = width
    self.height = height

  def print_info(self):
    print(f'宽是{self.width},高是{self.height}')

washer = Washer(10,20)
# 宽是10,高是20
washer.print_info()

str()

当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了_str_方法,那么就会打印从这个方法中return的数据

class Washer():

  def __init__(self,width,height):
    self.width = width
    self.height = height

  def __str__(self):
    return str(self.width) + str(self.height)

washer = Washer(10,20)
# 1020
print(washer)

del():这个方法不需要手工调用,因为释放内存空间,解释器会自动调用

在这里插入图片描述

call()

# __call__()
# __call__()方法的作用其实是把一个类的实例化对象变成了可调用对象,
#   也就是说把一个类的实例化对象变成了可调用对象,只要类里实现了__call__()方法就行。
# 如当类里没有实现__call__()时,此时的对象p 只是个类的实例,不是一个可调用的对象,
#   当调用它时会报错:‘Person’ object is not callable.
# 使用callable()方法可以判断某对象是否可以被调用。



class People(object):
    def __init__(self,name):
        self.name=name
    def __call__(self):
        print("hello "+self.name)
a = People('无忌!')
# hello 无忌!
a()                
# hello 无忌!
a.__call__()       



print('----------------------------------------')


class Person(object):
    def __init__(self,name):
        self.name=name
a = Person('无忌!')
# TypeError: 'Person' object is not callable
a()               

面向对象三大特征

  • 封装
    • 将属性和方法书写到类的里面的操作即为封装
    • 封装可以为属性和方法添加私有权限
  • 继承
    • 子类默认继承父类的所有属性和方法
    • 子类可以重写父类属性和方法
  • 多态
    • 传入不同的对象,产生不同的结果

继承(python有单继承和多继承)

python子类默认继承父类的所有属性和方法

单继承

class A:
  def __init__(self):
    self.num = 1

  def info_print(self):
    print(self.num)

class B(A):
  pass

# 1
b = B()
b.info_print()

多继承
注意
当一个类有多个类的时候,默认使用第一个父类的同名属性和方法

子类和父类具有同名属性和方法,默认使用子类的同名属性和方法

重写

class School(object):
  def __init__(self):
    self.kongfu = 'gongfu'

  def make_dinner(self):
    print(self.kongfu)

class Master:
  def __init__(self):
    self.kongfu = 'shaolin'

  def make_dinner(self):
    print(self.kongfu)

class Prentice(School,Master):
  def __init__(self):
    self.kongfu = 'wudang'

  def make_dinner(self):
    print(self.kongfu)

# wudang
prentice = Prentice()
prentice.make_dinner()

子类调用父类同名方法和属性

一般应该是使用super()的,待研究

class School(object):
  def __init__(self):
    self.kongfu = 'gongfu'

  def make_dinner(self):
    print(self.kongfu)

class Master:
  def __init__(self):
    self.kongfu = 'shaolin'

  def make_dinner(self):
    print(self.kongfu)

class Prentice(School,Master):
  def __init__(self):
    self.kongfu = 'wudang'

  def make_dinner(self):
    # 如果先调用了父类的方法和属性,父类属性会覆盖子类属性,
    # 故在调用属性前,先调用自己类的初始化
    print(self.kongfu)

  # 调用父类方法,为保证调用到的是父类的属性,
  # 必须在调用方法前调用父类的初始化
  def school_make_dinner(self):
    School.__init__(self)
    print(self.kongfu)

  def master_make_dinner(self):
    Master.__init__(self)
    print(self.kongfu)

prentice = Prentice()
# wudang
prentice.make_dinner()
# gongfu
prentice.school_make_dinner()
# shaolin
prentice.master_make_dinner()

私有属性和私有方法

  1. 定义
    在Python中,可以为实例属性和方法设置私有权限,即设置某个实例属性或实例方法不继承给子类

设置私有权限的方法:在属性名和方法名前面加两个_

class Person:

  def __init__(self):
    self.kongfu = 'stu'
    self.__money = 200

  # 获取私有属性
  def get_money(self):
    return self.__money

  # 修改私有属性
  def set_money(self,money):
    self.__money = money

person = Person()

# stu
print(person.kongfu)

# 200
print(person.get_money())

person.set_money(300)

# 300
print(person.get_money())

多态

多态指的是一类事物有多种形态(一个抽象类有多个子类,因而多态的概念依赖于继承)

  • 定义:多态是一种使用对象的方式,子类重写父类方法,调用不同子类对象的相同父类方法,可以产生不同的执行结果
  • 好处:调用灵活,有了多态,更容易编写出通用的代码,做出通用的编程,以适应需求的不断变化
  • 实现步骤
    • 定义父类,并提供公共方法
    • 定义子类,并重写父类方法
    • 传递子类对象给调用者,可以看到不同子类执行的效果是不同的
class Dog:
  def work(self):
    print('dog')

class PoliceDog(Dog):
  def work(self):
    print('PoliceDog')

class DrugDog(Dog):
  def work(self):
    print('DrugDog')

class Person():
  def work_with_dog(self,dog):
    dog.work()

person = Person()
policeDog = PoliceDog()
# PoliceDog
person.work_with_dog(policeDog)

异常

语法

try:
	可能发生错误的代码
except:
	如果出现异常执行的代码

捕获指定类型的异常

如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常

# 捕获一个指定类型的异常
try:
	print(num)
except NameError:
	print('有错误')

# 捕获多个指定类型的异常,捕获异常描述信息
try:
	print(1/0)
except(NameError,ZeroDivisionError) as result:
	print(result)
	print('有错误')

# 捕获所有异常
try:
	print(1/0)
except Exception as result:
	print(result)
	print('有错误')

没有异常要执行的代码

try:
	print(1)
except Exception as result:
	print(result)
else:
	print('没有异常的时候执行的代码')
# 无论是否异常都要执行的代码
finally:
	close()

自定义异常

在python中,抛出自定义异常的语法为raise异常类对象

# 自定义异常,继承Exception
class ShortInputError(Exception):
	
  def __init__(self,length,min_len):
    self.length = length
    self.min_len = min_len

  # 设置抛出异常的描述信息
  def __str__(self):
    return f'你输入的长度是{self.length},不能少于{self.min_len}个字符'

  
def main():
  try:
    con = input('请输入密码:')

    if len(con) < 3:
      raise ShortInputError(len(con),3)

  except Exception as result:
    print(result)
  else:
    print('密码已经输入完成')

main()

模块

Python模块(Module),是一个Python文件,以.py结尾,包含了Python对象定义和Python语句。

模块能定义函数,类和变量,模块里也能包含可执行的代码

导入模块的三种方法

# 方法一  import 模块名;模块名.功能
# import math

# 3.0   sqrt平方根
# print(math.sqrt(9))

# 方法二  from 模块名 import 功能1,功能2.。。;直接写函数/功能即可
# from math import sqrt
# 4.0
# print(sqrt(16))

# 方法三  from  模块名 import *;直接写函数/功能即可
from math import *
print(sqrt(25))

as定义别名

# 模块定义别名
import 模块名 as 别名

# 功能定义别名
from 模块名 import 功能 as 别名

制作模块

在Python中,每个Python文件都可以作为一个模块,模块的名字就是文件的名字。也就是说自定义模块名必须要符合标识符命名规则。

定义模块
新建一个Python文件,命名为my_module.py,并定义testA函数

def testA(a,b):
	print(a + b)

模块定位顺序

当导入一个模块,Python解析器对模块位置的搜索顺序是:

  1. 当前目录
  2. 如果不在当前目录,Python则搜索在shell变量PYTHONPATH下的每个目录
  3. 如果都找不到,Python会查看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/

模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。

注意

  • 自己的文件名不要和已有模块名重复,否则导致模块功能无法使用

  • 使用from 模块名 import 功能的时候,如果功能名字重复,调用到的是最后定义或导入的功能

all列表

如果一个模块文件中有__all__变量,
当使用from xxx import * 导入时,只能导入这个列表中的元素

  • cluTest模块/文件代码
__all__ = ['testA']
  
def testA():
  print('testA')
def testB():
    print('testB')
  • 导入模块文件的代码
from cluTest import * 

# testA
testA()
# NameError: name 'testB' is not defined
testB()

包将所有联系的模块组织在一起,即放到同一个文件夹下,
并且在这个文件夹创建一个名为 __init__.py文件,那么
这个文件夹就称之为包

制作包

New - Python Package - 输入包名 - 新建功能模块(有联系的模块)

注意:

新建包后,包内部会自动创建__init__.py文件,这个文件控制着包的导入行为

导入包的方法

# 方法一:
# import 包名.模块名
# 包名.模块名.目标

import my_package.my_module

my_package.my_module.info_print()


# 方法二:
# 注意:必须在__init__.py文件中添加__all__ = [],
# 控制允许导入的模块列表
# from 包名 import *
# 模块名.目标

from my_package import *

my_module.info_print()

部分知识引用自:
https://blog.csdn.net/come_from_pluto

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值