当前位置: 首页 > article >正文

Python函数和对象

函数

  • 函数的定义
'''
函数的定义:函数是将一段实现功能的完整代码,使用函数名称进行封装, 通过函数名称进行调用,从次达到一次编写,多次调用的目的

内置函数:输出函数 print();输入函数input(),列表定义的函数list().....
自定义函数:
    def 函数名称(参数列表):
        函数体
        [return 返回值列表]
韩式的调用:函数名(参数)
'''


# 计算累加和
def get_sum(num):  # num交形式参数
    s = 0
    for i in range(1, num + 1):
        s += i
    print(f'1-{num}的累加和为{s}')


get_sum(3)  # 1-3的累加和
get_sum(20)  # 1-20的累加和
get_sum(100)  # 1-100的累加和
  • 位置参数额使用
# 位置参数:是指调用时的参数个数和顺序必须与定义的参数个数和顺序相同
def happy_birthday(name, age):
    print('祝' + name + '生日快乐')
    print(str(age) + '岁生日快乐')


# happy_birthday('LL')#TypeError: happy_birthday() missing 1 required positional argument: 'age'
# happy_birthday(18,'ll')#TypeError: can only concatenate str (not "int") to str
happy_birthday('ll', 19)
  • 关键字传参的使用
# 位置参数:是指调用时的参数个数和顺序必须与定义的参数个数和顺序相同
# 关键字参数:是在函数调用时,使用"形参名称=值"的方式进行传参,传递三叔顺序可以和定义时参数的顺序不同
# 默认值参数:是在函数定义时,直接对形式参数进行赋值,在调用时如果该参数不传值,将使用默认值,如果该参数传值,则使用传递的值
def happy_birthday(name, age):
    print('祝' + name + '生日快乐')
    print(str(age) + '岁生日快乐')


# 关键字传参  定义的形参名称和关键字传参的名称相同
# happy_birthday(age=18,name1='LL')#TypeError: happy_birthday() got an unexpected keyword argument 'name1'
# happy_birthday(age=18,'LL')#SyntaxError: positional argument follows keyword argument
happy_birthday(age=18, name='LL')
happy_birthday('LL', age=18)
  • 默认值传参的使用
# 位置参数:是指调用时的参数个数和顺序必须与定义的参数个数和顺序相同
# 关键字参数:是在函数调用时,使用"形参名称=值"的方式进行传参,传递三叔顺序可以和定义时参数的顺序不同
# 默认值参数:是在函数定义时,直接对形式参数进行赋值,在调用时如果该参数不传值,将使用默认值,如果该参数传值,则使用传递的值
def happy_birthday(name='LL', age=18):
    print('祝' + name + '生日快乐')
    print(str(age) + '岁生日快乐')

#
happy_birthday()
# happy_birthday(18)#TypeError: can only concatenate str (not "int") to str
happy_birthday('ll')
happy_birthday(age=18)
happy_birthday(name="ll")


def fun(a,b=20):#a作为位置参数,b默认值参数
    pass

    # def fun(a=20,b):#语法错误,当位置参数和默认值参数同时存在的时候,位置参数在后会报错
    #     pass

#TODO 当位置参数和关键字参数同时存在的时候,应该遵循 位置参数在前,默认值参数在后
  • 可变参数的使用
# 可变参数:个数可变的位置参数
def fun(*param):
    print(type(param))
    for item in param:
        print(item)


fun(10, 20, 30)
fun(10)
fun("lll")
fun([10, 20, 30])  # 实际上传递的是一个参数
# 在调用时,参数前加一个星,会将列表进行解包
fun(*[10, 20, 30])
fun(*"lll")


# 个数可变的关键字参数
def fun2(**kwparam):
    print(type(kwparam))
    for key, value in kwparam.items():
        print(key, '====', value)


fun2(name='ll', age=19, height=180)
# fun2('ll',19,180)#TypeError: fun2() takes 0 positional arguments but 3 were given
d = {'name1': 'll', 'age2': 20, 'height3': 170}
# fun(d)#TypeError: fun() got an unexpected keyword argument 'name'
fun2(**d)
  • 函数返回值的使用
# 函数的返回值
def calc(a, b):
    print(a + b)


calc(10, 20)
print(calc(10, 20))  # None
print('-' * 60)


def calc2(a, b):
    s = a + b
    return s
print(calc2(10, 20))  # 30

get_s=calc2(10,30)
print(get_s)
print('-' * 60)

def get_sum(num):
    total_sum=0
    odd_sum=0
    even_sum=0
    for i in range(1,num+1):
        if i%2==0:
            even_sum+=i
        else:
            odd_sum+=i
        total_sum+=i
    return even_sum,odd_sum,total_sum
#解包数值
a,b,c = get_sum(10)
print(a)
print(b)
print(c)
print('-' * 60)
print(type(get_sum(10)))
print(*get_sum(10))
  • 局部变量的作用域
#变量的作用域:是指变量起作用的范围,根据范围作用的范围可分为局部变量和全局变量
#局部变量:在函数定义处的参数和函数内部定义的变量,作用范围:仅在函数内部,函数执行结束,局部变量的生命周期也结束
#全局变量:在函数外定义的变量或函数内部使用global关键字修饰的变量,作用范围:整个程序,程序与逆行结束,全局变量的生命周期才结束

def calc(a,b):
    s=a+b
    return s;
# print(a,b,s)#a,b是函数的参数,参数是局部变量,s函数中定义的变量,为局部变量
result = calc(10,30)
print(result)
  • 全局变量的作用域
# 变量的作用域:是指变量起作用的范围,根据范围作用的范围可分为局部变量和全局变量
# 局部变量:在函数定义处的参数和函数内部定义的变量,作用范围:仅在函数内部,函数执行结束,局部变量的生命周期也结束
# 全局变量:在函数外定义的变量或函数内部使用global关键字修饰的变量,作用范围:整个程序,程序与逆行结束,全局变量的生命周期才结束
'''
匿名函数lambda是指没有名字的函数,这种函数只能使用一次,一般是在函数的函数体只有一句代码且只有一个返回值时,可以使用匿名函数来简化
语法结构: result = lambda 参数列表:表达式

'''
a = 10


def calc(x, y):
    return a + x + y


result = calc(10, 30)
print(a)
print(calc(10, 20))


def calc2(x, y):
    a = 200  # 局部变量
    return a + x + y  # 此处的a为局部变量,为当前函数中定义的a


print(calc2(100, 300))  # 600


def calc3(x, y):
    global s
    s = 1000  # 声明和赋值,必须分开执行
    return s + x + y  # s是在函数中定义的变量,但是使用了global关键字声明,这个变量s变成了全局变量

print(s)#NameError: name 's' is not defined =========>s global修饰的参数,必须在函数被调用后,才能使用否则报错

print(calc3(1000, 3000))
print(s)
  • 匿名函数的使用
'''
匿名函数lambda是指没有名字的函数,这种函数只能使用一次,一般是在函数的函数体只有一句代码且只有一个返回值时,可以使用匿名函数来简化
语法结构: result = lambda 参数列表:表达式

'''


def calc(a, b):
    return a + b


print(calc(10., 20))

# 匿名函数
result = lambda a, b: a + b
print(type(result))  # <class 'function'>

# 使用匿名函数
print(result(10, 50))

print('-' * 66)
lst = [10, 20, 30, 40, 50]
for i in range(len(lst)):
    print(lst[i])
print()

for i in range(len(lst)):
    result = lambda x: x[i]
    print(result(lst))
print('-' * 66)

student_scores = [
    {'name': '张三', 'score': 98},
    {'name': '李四', 'score': 90},
    {'name': '王五', 'score': 95},
    {'name': '李一', 'score': 66}
]
#对列表进行排序,排序规则,按成绩进行排序
print(student_scores)
print('-' * 66)

student_scores.sort(key=lambda x:x.get('score'),reverse=True)

print(student_scores)
'''
递归函数
1.在一个函数的函数体内调用该函数本身,该函数就是递归函数
2.一个完整的递归操作由两部分组成,一部分时递归调用,一部分时递归终止条件,一般可使用if-else结构来判断递归的调用和递归的终止
'''
  • 递归函数
'''
递归函数
1.在一个函数的函数体内调用该函数本身,该函数就是递归函数
2.一个完整的递归操作由两部分组成,一部分时递归调用,一部分时递归终止条件,一般可使用if-else结构来判断递归的调用和递归的终止

斐波那契数列:f(n)=f(n-1)+f(n-2)
'''
def fac(n):#n的阶乘,n!=n
    if n==1:
        return 1
    else:
        return n*fac(n-1)#自己调用自己

print(fac(5))#120
// 斐波那契数列
def fac2(n):
    if n == 1 or n == 2:
        return 1
    else:
        return fac(n - 1) + fac(n - 2)


print(fac2(9))
print('-' * 66)
for i in range(1, 10):
    print(fac2(i),end='\t')
  • 内置函数
    • 数据类型转换函数的使用
'''
常用的内置函数
1.数据类型转换函数
函数名称                    描述说明
bool(obj)                 获取指定对象obj的布尔值
str(obj)                  将指定对象obj转成字符串类型
int(x)                    将x转成int类型
float(x)                  将x转成float类型
list(sequence)            将序列转成列表类型
tuple(sequence)           将序列转成元组类型
set(sequence)             将序列转成集合类型
'''
print('非空字符串的布尔值:', bool('hello'))  # True
print('空字符串的布尔值:', bool(''))  # False
print('空列表的布尔值:', bool([]))  # False
print('空列表的布尔值:', bool(list()))  # False
print('空元组的布尔值:', bool(()))  # False
print('空元组的布尔值:', bool(tuple()))  # False
print('空字典的布尔值:', bool({}))  # False
print('空字典的布尔值:', bool(dict()))  # False
print('--' * 20 + '将其他类型转成字符串类型'+'--' * 20)
print('非0数值的布尔值:', bool(12))  # True
print('整数0的布尔值:', bool(0))  # False
print('浮点数0.0的布尔值:', bool(0.0))  # False
# 将其他类型转成字符串类型
print('--' * 20 + '将其他类型转成字符串类型'+'--' * 20)
lst = [1, 2, 3, 4, ]
print(type(lst), lst)
s = str(lst)
print(type(s), s)
#float类型和str类型转成int类型
print('--' * 20 + 'float类型和str类型转成int类型'+'--' * 20)

print(int(98.7)+int('100'))
#注意事项
# print(int('98.7'))#ValueError: invalid literal for int() with base 10: '98.7'
# print(int('a'))#ValueError: invalid literal for int() with base 10: 'a'
#int类型和str类型转成float类型
print('--' * 20 + 'int类型和str类型转成float类型'+'--' * 20)
print(float(98)+float('100')+float('10.111'))

print('--' * 20 + 'str类型转成list类型'+'--' * 20)
s='hello'
print(list(s))

print('--' * 20 + '列表,元组,集合的转换'+'--' * 20)
seq=range(1,10)
print(tuple(seq))
print(list(seq))
print(set(seq))
- 数学函数的使用
'''
常用的内置函数
1.数学函数
函数名称                    描述说明
abs(x)                 获取x的绝对值
divmod(x,y)            获取x与y的商和余数
max(sequence)          获取sequence的最大值
min(sequence)          获取sequence的最小值
sum(iter)              对可迭代对象进行求和运算
pow(x,y)               获取x的y次幂
round(x,d)             对x进行保留d位小数,结果四舍五入
'''

print('绝对值:', abs(-100), abs(99), abs(0))
print('商和余数:', divmod(11, 4))
print('最大值:', max('hello'))  # 安装ASCII码值进行计算
print('最大值:', max([1, 2, 37, 4, 8]))
print('最小值:', min('hello'))  # 安装ASCII码值进行计算
print('最小值:', min([1, 2, 37, 4, 8]))
print('求和:', sum([10, 20, 30]))
print('x的y次幂:', pow(2, 5))
print('四舍五入:', round(2.5675))
print('四舍五入:', round(2.4675))
print('四舍五入:', round(2.4673, 3))
print('四舍五入:', round(2.4673, -1))  # -1位 个数位置进行四舍五入
print('四舍五入:', round(5.4673, -1))  # -1位 个数位置进行四舍五入
print('四舍五入:', round(45.4673, -2))  # -2位 十数位置进行四舍五入
print('四舍五入:', round(55.4673, -2))  # -2位 十数位置进行四舍五入
- 迭代器操作函数的使用
'''
常用的内置函数
1.迭代器操作函数
函数名称                    描述说明
sorted(iter)              对可迭代对象进行排序
reversed(sequence)        反转序列生成新的迭代器对象
zip(iter1,iter2)          将iter1与iter2打包成元组,并返回一个可迭代的zip对象
enumerate(iter)           根据iter对象创建一个sequence对象
all(iter)                 判断可迭代对象iter中所有元素的布尔值是否都为Ture
any(iter)                 判断可迭代对象iter中所有元素的布尔值是否都为False
next(iter)                获取迭代器的下一个元素
filter(function,iter)     通过指定条件过滤序列并返回一个迭代器对象
map(function,iter)        通过函数function对可迭代对象iter的操作返回一个迭代器对象
'''
lst = [54, 56, 57, 4, 567, 34]
print('原数据:', lst)
# 排序操作
print('-' * 10 + '排序操作' + '-' * 10)
asc_lst = sorted(lst)
desc_lst = sorted(lst, reverse=True)
print('正序:', asc_lst)
print('降序:', desc_lst)
# 反向操作
print('-' * 10 + '反向操作' + '-' * 10)
new_lst = reversed(lst)
print(type(new_lst), new_lst, list(
    new_lst))  # <class 'list_reverseiterator'> <list_reverseiterator object at 0x000002598FFA7DC0> [34, 567, 4, 57, 56, 54]

# zip操作
print('-' * 10 + 'zip操作' + '-' * 10)
x = ['a', 'b', 'c', 'd']
y = [10, 20, 30, 40, 50]
zipObj = zip(x, y)
print(type(zip(zipObj)), zipObj,
      list(zipObj))  # <class 'zip'> <zip object at 0x00000235E45E11C0> [('a', 10), ('b', 20), ('c', 30), ('d', 40)]

# enumerate
print('-' * 10 + 'enumerate' + '-' * 10)
enumX = enumerate(x, start=1)
enumY = enumerate(y, start=1)
print(type(enumX), enumX, tuple(
    enumX))  # <class 'enumerate'> <enumerate object at 0x000001A7F9F3D1C0> ((1, 'a'), (2, 'b'), (3, 'c'), (4, 'd'))
print(type(enumY), enumY, list(
    enumY))  # <class 'enumerate'> <enumerate object at 0x000001A7F9F3CE50> [(1, 10), (2, 20), (3, 30), (4, 40), (5, 50)]
# all
print('-' * 10 + 'all' + '-' * 10)
lst2 = [10, 20, '', 30]
print(all(lst))  # True
print(all(lst2))  # Flase
# any
print('-' * 10 + 'any' + '-' * 10)
print(any(lst))  # True
print(any(lst2))  # True

# next
print('-' * 10 + 'next' + '-' * 10)
x2 = ['a', 'b', 'c', 'd']
y2 = [10, 20, 30, 40, 50]
zipObj2 = zip(x2, y2)
print(next(zip(zipObj2)))
print(next(zip(zipObj2)))
print(next(zip(zipObj2)))

# filter
print('-' * 10 + 'filter' + '-' * 10)


def fun(num):
    return num % 2 == 1


obj = filter(fun, range(10))
print(list(obj))  # [1, 3, 5, 7, 9]


def upper(x):
    return x.upper()


new_lst2 = ['hello', 'World', 'python']
obj2 = map(upper, new_lst2)
print(list(obj2))  # ['HELLO', 'WORLD', 'PYTHON']
- 其他常用函数的使用
'''
常用的内置函数
1.迭代器操作函数
函数名称                            描述说明
format(value,format_spec)          将value以format_spec格式进行显示
len(s)                             获取s的长度或s元素的个数
id(obj)                            获取对象的内存地址
type(x)                            获取x的数据类型
eval(s)                            执s这个字符串所表示的Python代码
'''
# format
print(format(3.14, '20'))  # 数值型默认右对齐
print(format('hello', '20'))  # 字符串默认左对齐
print(format('hello', '*<20'))  # <左对齐,*表示填充符,20表示显示宽度
print(format('hello', '*>20'))  # <右对齐,*表示填充符,20表示显示宽度
print(format('hello', '*^20'))  # <居中对齐,*表示填充符,20表示显示宽度

对象

  • 对象的数据类型
a=10
b=3.14
c='hello'
d=True
print(type(a))
print(type(b))
print(type(c))
print(type(d))
  • 自定义数据类型
'''
类和对象
自定义数据类型的语法结构
class 类名():
    pass
    
创建对象的语法格式
对象名 = 类名()
'''


# 编写一个Person
class Person():
    pass


# 编写一个Cat类
class Cat():
    pass


# 编写一个Dog类
class Dog:
    pass


# 编写一个Student类
class Student:
    pass
  • 类的组成
'''
类的组成
1.类属性:直接定义在类中,方法外的变量
2.实例属性:定义在_init_方法中,使用self打点的变量
3.实例方法:定义在类中的函数,而且自带参数的self
4.静态方法:使用@staticmethod修饰的方法
5.类方法:使用@classmethod修饰的方法
'''


class Student:
    # 类属性:直接定义在类中,方法外的变量
    school = '合肥高新小学'
    #初始化方法
    def __init__(self, xm, age):  # xm,age是方法参数,属于局部变量,xm,age的作用域是整个__init__方法
        self.name = xm  # =左侧是实例属性,xm是局部变量,将局部变量的值xm赋值给实例属性self.name
        self.age = age  # 实例的名称和局部变量的名称可以相同

    #定义在类中的函数,而且自带参数的self
    def show(self):
        print(f'我叫{self.name},今年{self.age}岁')

    #静态方法
    @staticmethod
    def sm():
        print('这是一个静态方法,不能调用实例属性,也不能调用实例方法')
    #类方法
    @classmethod
    def cm(cls):
        print('这是一个类方法,不能调用实例属性,也不能调用实例方法')

#创建类的对象
stu=Student('LL',18)#为什么传了两个参数,因为__init__方法中,有两个参数,self是自带参数,无需手动传入
#实例属性,使用对象名进行打点调用的
print(stu.age,stu.name)
#类属性 直接使用类名打点调用
print(Student.school)

#实例方法,使用对象名进行打点调用的
stu.show()
#类方法,使用类名进行打点调用的
Student.cm()
#静态方法,使用类名进行打点调用的
Student.sm()

# 创建多个对象
stu = Student('ll', 18)
stu2 = Student('ll2', 19)
stu3 = Student('ll3', 20)
stu4 = Student('ll4', 21)

print(type(stu))
print(type(stu2))
print(type(stu3))
print(type(stu4))
Student.school = 'newSchool'  # 给类的类属性赋值
# 将学生对象存储到列表中
lst = [stu, stu2, stu3, stu4]  # 列表中的元素是Student类型的参数

for item in lst:  # item是列表中的元素,是Student类型的对象
    item.show()
    print(item.school)
  • 动态绑定属性和方法
'''
类的组成
1.类属性:直接定义在类中,方法外的变量
2.实例属性:定义在_init_方法中,使用self打点的变量
3.实例方法:定义在类中的函数,而且自带参数的self
4.静态方法:使用@staticmethod修饰的方法
5.类方法:使用@classmethod修饰的方法
'''


class Student:
    # 类属性:直接定义在类中,方法外的变量
    school = '合肥高新小学'

    # 初始化方法
    def __init__(self, xm, age):  # xm,age是方法参数,属于局部变量,xm,age的作用域是整个__init__方法
        self.name = xm  # =左侧是实例属性,xm是局部变量,将局部变量的值xm赋值给实例属性self.name
        self.age = age  # 实例的名称和局部变量的名称可以相同

    # 定义在类中的函数,而且自带参数的self
    def show(self):
        print(f'我叫{self.name},今年{self.age}岁')


# 创建两个student类型的对象
stu = Student('ll', 18)
stu2 = Student('ll2', 20)
print(stu.name, stu.age)
print(stu2.name, stu2.age)
# 为stu2动态绑定一个实例属性
stu2.gender = '男'
print(stu2.name, stu2.age, stu2.gender)


# print(stu.gender)#AttributeError: 'Student' object has no attribute 'gender'
# 动态绑定方法
def introduce():
    print('我是一个普通函数,我被动绑定成了stu2对象的方法')


stu2.fun = introduce()  # 函数的一个赋值
# 调用
stu2.fun
# stu.fun#AttributeError: 'Student' object has no attribute 'fun'

'''
面向对象的三大特征
封装:隐藏内部细节,对外提供操作方式
继承:是在函数调用时,使用"形参名称=值"的方式进行传参,传递参数顺序可以与定义时参数的顺序不同
多态:是在函数定义时,直接对形式参数进行赋值,在调用时如果该参数不传值,将使用默认值,如果该参数传值,则使用传递的值
'''
  • 权限控制
'''
权限控制:是通过堆属性或方法天啊及单下划线,双下划线,以及首位双下划线来实现
单下划线开头:以单下划线开头的属性或方法表示protected,受保护的成员,这类成员被视为仅供内部使用,允许类本身和子类进行访问,但实际上它可以被外部代码访问
双下划线开头:表示private私有的成员,这类成员只允许定义该属性或方法的类本身进行访问
首尾双下划线:一般表示特殊的方法
'''


class Student():
    # 首位双下划线
    def __init__(self, name, age, gender):
        self._name = name  # self._name受保护的,只能本类和子类访问protected
        self.__age = age  # self.__age私有的,只能本类访问private私有
        self.gender = gender  # 普通实例属性,类内部,外部,子类均可以访问

    def _fun1(self):
        print('本类和子类访问')

    def __fun2(self):
        print('只有定义的类可以访问')

    def show(self):  # 普通的实例方法
        self._fun()  # 类本身访问受保护的方法
        self.__fun2()  # 类本身访问私有的方法
        print(self._name)
        print(self.__age)
        print(self.gender)


# 创建一个学生类的对象
stu = Student('LL', 18, '男')
# 类的外部
print(stu._name)
# print(stu.__age)#AttributeError: 'Student' object has no attribute '__age'. Did you mean: '_name'?
# 调用受保护的实例方法
stu._fun1()  # 子类及本身可以访问
# 私有方法
# stu.__fun2()#AttributeError: 'Student' object has no attribute '__fun2'. Did you mean: '_fun1'?
#私有的实例属性和方法是真的不能访问吗?
print(stu._Student__age)
stu._Student__fun2()

print(dir(stu))
  • 属性的设置
'''
权限控制:是通过堆属性或方法天啊及单下划线,双下划线,以及首位双下划线来实现
单下划线开头:以单下划线开头的属性或方法表示protected,受保护的成员,这类成员被视为仅供内部使用,允许类本身和子类进行访问,但实际上它可以被外部代码访问
双下划线开头:表示private私有的成员,这类成员只允许定义该属性或方法的类本身进行访问
首尾双下划线:一般表示特殊的方法
'''


class Student():
    # 首位双下划线
    def __init__(self, name, gender):
        self.name = name
        self.__gender = gender  # self.__gender是私有的实例属性

    # 使用@property修饰方法,将方法转成属性使用
    @property
    def gender(self):
        return self.__gender

    @gender.setter
    def gender(self, value):
        if value != '男' and value != '女':
            print('性别有无,已将性别默认设置为男')
            self.__gender = '男'
        else:
            self.__gender = value


stu = Student('LL', '女')
print(stu.name, '的性别是:', stu.gender)
# 尝试修改属性值
# stu.gender = '男'  # AttributeError: property 'gender' of 'Student' object has no setter

stu.gender='其他'
print(stu.name, '的性别是:', stu.gender)
stu.gender='女'
print(stu.name, '的性别是:', stu.gender)

'''
继承:
在Python中一个子了可以继承N多个父类
一个父类也可以拥有N多个子类
如果一个类没有继承任何类,那么这个类默认继承的是object类
继承的语法结构
class 类名(父类1,父类2,父类3,...,父类N):
    pass
'''
  • 继承和多继承
'''
继承:
在Python中一个子了可以继承N多个父类
一个父类也可以拥有N多个子类
如果一个类没有继承任何类,那么这个类默认继承的是object类
继承的语法结构
class 类名(父类1,父类2,父类3,...,父类N):
    pass
'''


class Persion():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print(f'大家好,,我叫{self.name},今年{self.age}岁')


# Student继承Persion类
class Student(Persion):
    def __init__(self, name, age, stuno):
        super().__init__(name, age)  # 调用父类的初始化方法
        self.stuno = stuno


class Doctor(Persion):
    def __init__(self, name, age, department):
        super().__init__(name, age)  # 调用父类的初始化方法
        self.department = department


# 创建子类
stu = Student('StudentLL', 20, '1001')
stu.show()

doctor = Doctor('DoctorLL', 38, '外科')
doctor.show()

// 多继承
class FatherA():
    def __init__(self, name):
        self.name = name

    def showA(self):
        print('父类A中的方法')


class FatherB():
    def __init__(self, age):
        self.age = age

    def showB(self):
        print('父类B中的方法')


# 多继承
class Son(FatherA, FatherB):
    def __init__(self, name, age,gender):
        # 需要调用两个父类的初始化方法
        FatherA.__init__(self, name)
        FatherB.__init__(self, age)
        self.gender=gender

son=Son('LL',18,'男')
son.showA()
son.showB()
  • 方法重写
'''
方法重写:
子类继承了父类就拥有了父类中的公有成员和受保护的成员
父类的方法并不能完全适合子类的需求,这个时候子类就可以重写父类的方法
子类在重写父类的方法时,要求方法的名称必须与父类方法的名称相同,在子类重写后的方法可以通过super().xxx调用父类中的方法
'''

'''
多态:指的就是'多种形态',即便不知道变量所引用的对象到底是什么类型,仍然可以通过这个变量调用对象的方法
在程序运行过程中,根据比哪里所引用对象的数据类型,动态决定调用那个对象中的方法
Python语言中的多态,根本不关心对象的数据类型,也不关系类之间是是否存在继承关系,只关心对象的行为(方法),只要不同的类中有相同的方法,即可实现多态
'''


class Persion():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print(f'大家好,,我叫{self.name},今年{self.age}岁')


# Student继承Persion类
class Student(Persion):
    def __init__(self, name, age, stuno):
        super().__init__(name, age)  # 调用父类的初始化方法
        self.stuno = stuno

    def show(self):
        super().show()
        print(f'我来自xxx学校,我的学号是{self.stuno}')


class Doctor(Persion):
    def __init__(self, name, age, department):
        super().__init__(name, age)  # 调用父类的初始化方法
        self.department = department

    def show(self):
        # super().show()
        print(f'大家好,,我叫{self.name},今年{self.age}岁,我的工作科室是{self.department}')


# 创建子类
stu = Student('StudentLL', 20, '1001')
stu.show()

doctor = Doctor('DoctorLL', 38, '外科')
doctor.show()
  • 多态
'''
多态:指的就是'多种形态',即便不知道变量所引用的对象到底是什么类型,仍然可以通过这个变量调用对象的方法
在程序运行过程中,根据比哪里所引用对象的数据类型,动态决定调用那个对象中的方法
Python语言中的多态,根本不关心对象的数据类型,也不关系类之间是是否存在继承关系,只关心对象的行为(方法),只要不同的类中有相同的方法,即可实现多态
'''
'''
Objct类
所有类直接或间接的父类
所有类都拥有object类的属性和方法
object类中特殊的方法           功能描述
_new_()                     由系统调用,用于创建对象
_init_()                    创建对象时手动调用,用于初始化对象属性值
_str_()                     对象的描述,返回值是str类型,默认输出对象的内存地址
'''

class Persion():
    def eat(self):
        print('人,吃五谷杂粮')


class Cat():
    def eat(self):
        print('猫,喜欢吃鱼')


class Dog():
    def eat(self):
        print('狗,喜欢啃骨头')


# 这三个类中都有一个同名的方法 :eat
# 编写函数
def fun(obj):  # obj是函数的形式参数,在定义处不知道这个形参的具体数据类型
    obj.eat()  # 通过这个变量obj(对象)调用eat方法


per = Persion()
cat = Cat()
dog = Dog()
# 调用fun函数
per.eat()#Python中的多态,不关心对象的数据类型,只关心对象是否具有同名的方法
cat.eat()
dog.eat()
  • 查看指定对象的属性
'''
Objct类
所有类直接或间接的父类
所有类都拥有object类的属性和方法
object类中特殊的方法           功能描述
_new_()                     由系统调用,用于创建对象
_init_()                    创建对象时手动调用,用于初始化对象属性值
_str_()                     对象的描述,返回值是str类型,默认输出对象的内存地址
'''


class Persion(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print(f'大家好,我叫:{self.name},今年{self.age}岁了')


# 创建Persion类的对象
per = Persion('LL', 19)  # 创建对象的时候会自动调用__init__()方法
lst = dir(per)
for item in lst:
    print(item)

print(per)  # 自动调用了__str__方法     <__main__.Persion object at 0x0000016D520D41D0>
  • __str__方法重写前后
'''
Objct类
所有类直接或间接的父类
所有类都拥有object类的属性和方法
object类中特殊的方法           功能描述
_new_()                     由系统调用,用于创建对象
_init_()                    创建对象时手动调用,用于初始化对象属性值
_str_()                     对象的描述,返回值是str类型,默认输出对象的内存地址
'''
重写前
class Persion(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print(f'大家好,我叫:{self.name},今年{self.age}岁了')

    def __str__(self):
        return '这是一个人类,具有name和age两个实例属性'  # 返回值为字符串


# 创建Persion类的对象
per = Persion('LL', 19)  # 创建对象的时候会自动调用__init__()方法
print(per)

// 重写后
class Persion(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def show(self):
        print(f'大家好,我叫:{self.name},今年{self.age}岁了')


# 创建Persion类的对象
per = Persion('LL', 19)  # 创建对象的时候会自动调用__init__()方法
lst = dir(per)
for item in lst:
    print(item)

print(per)  # 自动调用了__str__方法     <__main__.Persion object at 0x0000016D520D41D0>

  • 特殊方法
'''
特殊方法
运算符         特殊方法                        功能描述
+             __add__()                     执行加法运算
-             __sub__()                     执行减法运算
< <= ==       __lt__(),__le__(),__eq__()    执行比较运算
> >= !=       __gt__(),__ge__(),__ne__()   执行比较运算
* /           __mul__(),__truediv__()       执行乘法运算,执行非整除运算
% //          __mod__(),__floordiv__()      执行取余运算,整除运算
**            __pow__()                     执行幂运算
'''
'''
特殊属性
特殊属性                       功能描述
obj.__dict__                对象的属性字典
obj.__class__               对象所属的类
obj.__bases__               类的父类元组
obj.__base__                类的父类
obj.__mor__                 类的层次机构
obj.__subclasses__()        类的子类列表
'''
a = 10
b = 20
print(dir(10))
print('-' * 30 + '__add__' + '-' * 30)
print(a + b)
print(a.__add__(b))
print('-' * 30 + '__sub__' + '-' * 30)
print(a - b)
print(a.__sub__(b))
print('-' * 30 + '__lt__' + '-' * 30)
print(a < b)
print(a.__lt__(b))
print('-' * 30 + '__le__' + '-' * 30)
print(a <= b)
print(a.__le__(b))
print('-' * 30 + '__eq__' + '-' * 30)
print(a == b)
print(a.__eq__(b))
print('-' * 30 + '__gt__' + '-' * 30)
print(a > b)
print(a.__gt__(b))
print('-' * 30 + '__ge__' + '-' * 30)
print(a >= b)
print(a.__ge__(b))
print('-' * 30 + '__ne__' + '-' * 30)
print(a != b)
print(a.__ne__(b))

print('-' * 30 + '__mul__' + '-' * 30)
print(a * b)
print(a.__mul__(b))

print('-' * 30 + '__truediv__' + '-' * 30)
print(a / b)
print(a.__truediv__(b))

print('-' * 30 + '__mod__' + '-' * 30)
print(a % b)
print(a.__mod__(b))

print('-' * 30 + '__floordiv__' + '-' * 30)
print(a // b)
print(a.__floordiv__(b))
print('-' * 30 + '__pow__' + '-' * 30)
print(a ** b)
print(a.__pow__(b))
  • 特殊属性
'''
特殊方法
运算符         特殊方法                        功能描述
+             __add__()                     执行加法运算
-             __sub__()                     执行减法运算
< <= ==       __lt__(),__le__(),__eq__()    执行比较运算
> >= !=       __gt__(),__ge__(),__ne__()   执行比较运算
* /           __mul__(),__truediv__()       执行乘法运算,执行非整除运算
% //          __mod__(),__floordiv__()      执行取余运算,整除运算
**            __pow__()                     执行幂运算
'''
'''
特殊属性
特殊属性                       功能描述
obj.__dict__                对象的属性字典
obj.__class__               对象所属的类
obj.__bases__               类的父类元组
obj.__base__                类的父类
obj.__mro__                 类的层次机构
obj.__subclasses__()        类的子类列表
'''
class A:
    pass
class B:
    pass
class C(A,B):
    def __init__(self,name,age):
        self.name=name
        self.age=age

#创建对象
a=A()
b=B()
c=C('LL',19)

print('对象a的属性字典:',a.__dict__)
print('对象b的属性字典:',b.__dict__)
print('对象c的属性字典:',c.__dict__)
print('-'*66)
print('对象a所属的类:',a.__class__)
print('对象b所属的类:',b.__class__)
print('对象c所属的类:',c.__class__)
print('-'*66)
print('A类的父类元组:',A.__bases__)
print('B类的父类元组:',B.__bases__)
print('C类的父类元组:',C.__bases__)

print('-'*66)
print('A类的父类:',A.__base__)
print('B类的父类:',B.__base__)
print('C类的父类:',C.__base__)#A类,如果继承了N个父类,结果只显示第一个父类

print('-'*66)
print('A类的层次机构:',A.__mro__)
print('B类的层次机构:',B.__mro__)
print('C类的层次机构:',C.__mro__)
print('-'*66)
print('A类的子类列表:',A.__subclasses__())
print('B类的子类列表:',B.__subclasses__())
print('C类的子类列表:',C.__subclasses__())
  • 类的深拷贝和浅拷贝
'''
类的深拷贝与浅拷贝
变量的赋值:只是形成两个变量,实际上还是指向同一个对象
浅拷贝:拷贝时,对象包含的子类对象内容不拷贝,因此,元对象与拷贝对象会引用同一个子对象
深拷贝:使用copy模块的deep copy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同
'''
import copy


class CPU():
    pass


class Disk():
    pass


class Computer():
    def __init__(self, cpu, disk):
        self.cpu = cpu
        self.disk = disk


# 创建CPU和Disk对象
cpu = CPU()
disk = Disk()
# 创建一个计算机对象
computer = Computer(cpu, disk)

# 变量(对象)的赋值
print('-'*30+'变量(对象)的赋值'+'-'*30)
computer1 = computer

print(computer, '子对象的内存地址:', computer.cpu, computer.disk)  # <__main__.Computer object at 0x000002A9F40B47D0> 子对象的内存地址: <__main__.CPU object at 0x000002A9F40B4750> <__main__.Disk object at 0x000002A9F40B4790>
print(computer1, '子对象的内存地址:', computer1.cpu, computer1.disk)  # <__main__.Computer object at 0x000002A9F40B47D0> 子对象的内存地址: <__main__.CPU object at 0x000002A9F40B4750> <__main__.Disk object at 0x000002A9F40B4790>
#类对象的浅拷贝
print('-'*30+'浅拷贝'+'-'*30)
computer2 = copy.copy(computer) #computer2是新产生的对象,computer2的子对象 cpu disk不变
print(computer, '子对象的内存地址:', computer.cpu, computer.disk)  # <__main__.Computer object at 0x000002A9F40B47D0> 子对象的内存地址: <__main__.CPU object at 0x000002A9F40B4750> <__main__.Disk object at 0x000002A9F40B4790>
print(computer2, '子对象的内存地址:', computer2.cpu, computer2.disk)  # <__main__.Computer object at 0x0000019CC2B96D90> 子对象的内存地址: <__main__.CPU object at 0x0000019CC2B94E90> <__main__.Disk object at 0x0000019CC2B947D0>

#类对象的浅拷贝
print('-'*30+'深拷贝'+'-'*30)
computer3 = copy.deepcopy(computer) #computer2是新产生的对象,computer2的子对象 cpu disk也会重新创建
print(computer, '子对象的内存地址:', computer.cpu, computer.disk)  # <__main__.Computer object at 0x000002A9F40B47D0> 子对象的内存地址: <__main__.CPU object at 0x000002A9F40B4750> <__main__.Disk object at 0x000002A9F40B4790>
print(computer3, '子对象的内存地址:', computer3.cpu, computer3.disk)  # <__main__.Computer object at 0x0000019CC2B96D90> 子对象的内存地址: <__main__.CPU object at 0x0000019CC2B94E90> <__main__.Disk object at 0x0000019CC2B947D0>

http://www.kler.cn/a/385699.html

相关文章:

  • R语言机器学习与临床预测模型69--机器学习模型解释利器:SHAP
  • Django Form
  • Vue 3 中,computed 和 watch的区别
  • python识别ocr 图片和pdf文件
  • git修改当前分支名称并推送到远程仓库
  • Linux系统的网络设置
  • 【Rust.Crate之tracing 诊断系统】
  • 星空天文 2.0.1| 完全免费的观星软件,无注册登录,天文爱好者必备。
  • 如何让3dsMax渲染效果更逼真好看?
  • HarmonyOS 移
  • Unity网络通信(part7.分包和黏包)
  • 3.2cpu
  • 初级数据结构——顺序表
  • Pr 视频过渡:沉浸式视频 - VR 球形模糊
  • 音视频入门基础:FLV专题(23)——FFmpeg源码中,获取FLV文件音频信息的实现(下)
  • MySQL 和 PostgreSQL 常见区别和联系
  • 信息收集(CISP-PTE笔记)
  • qt5将程序打包并使用
  • 区间数位和
  • 抗辐照MCU芯片工艺解析:如何保障芯片的可靠性
  • 用户登录密码存储加密策略(附Python 和 bcrypt 库进行安全密码验证)
  • 【NLP】使用 SpaCy 通过 LLM 合成数据微调 NER 模型
  • 大数据新视界 -- 大数据大厂之 Impala 性能优化:融合机器学习的未来之路(上 (2-2))(11/30)
  • 《应用力学学报》
  • PyTorch nn.Embedding() 嵌入层详解和要点提醒
  • CSS3中的3D变换(3D空间与景深、透视点的位置、3D位移、3D旋转、3D缩放、3D多重交换、背部可见性)