# coding=utf-8 # 函数与类 print(f"{"函数":*^50}") # 什么是函数:就是对某一段代码进行封装,方便不断重复使用 # 定义函数 def 函数(参数="默认", 参数1="默认1"): print(f"函数体{参数},{参数1}") return "返回值,没有可以不写" # 调用函数 函数(1, 2) 函数(参数=1, 参数1=2) 函数() # 可变参数*,** # Python 中,函数可以使用可变参数来处理不确定数量的参数。可变参数分为两种类型: # # 可变位置参数 *args(允许函数接受任意数量的位置参数。这些参数会被打包成一个元组,可以在函数内部进行操作。) # 可变关键字参数 **kwargs(允许函数接受任意数量的关键字参数。这些参数会被打包成一个字典,字典的键是参数名,值是参数值。) def 变位(*要一个星): for i in 要一个星: print(i) return print("完成了可变位置") def 变关键字(**要两个个星): for i, j in 要两个个星.items(): print(f"key:{i},value:{j}") return print("完成了可变关键字") 变位(1, 2, 3, 4, 5) 变关键字(name="Alice", age=30, city="New York") # 组合使用 def 组合(普通, *变位, **关键): print(f"Name: {普通}") print("Additional Information:") for arg in 变位: print(f"- {arg}") for key, value in 关键.items(): print(f"{key}: {value}") return print("组合完成") 组合("Alice", 30, "Engineer", city="New York", hobby="Reading") # 作用域 # 局部作用域(Local):函数内部定义的变量,只能在函数内访问。 # 嵌套作用域(Enclosing):嵌套函数的外层函数中的变量,内部函数可以访问外层函数的变量。 # 全局作用域(Global):模块(文件)最外层的变量,整个模块内都可以访问。 # 内建作用域(Built-in):Python 自带的全局函数和变量,如 print(),在任何地方都可以使用。 # 当使用一个变量时,先从局部找,找不到再向外层函数、全局、内建作用域依次查找。 a = 1 b = 2 c = 3 def x1(): a = 4 b = 5 def x2(): global b a = 6 # global a # 如果先用a,在global就会报错 print(a, b, c) print(a, b, c) # global 关键字用于声明一个变量是全局变量,但它必须在你尝试访问或使用该变量之前声明。 pass x2() pass x1() # 函数类型 print(x1) # 函数可以作为另一个的返回值,也可以作为另一个的参数 def test(): print("作为参数或者返回值") pass def 参数(a): a() pass def 返回值(): return test() 参数(test) 返回值() # 函数名和变量名共享同一个命名空间,因此函数名可以被变量覆盖。要避免这种冲突,建议避免使用与函数相同的变量名。 # filter筛选,map映射filter/map(函数x,可迭代类型),最后数据建议用list一下 # 从迭代对象中逐一调取元素到函数x中 # 函数x用于测试每个元素的函数。该函数返回 True 或 False。 # 返回一个过滤后的迭代器对象,包含所有通过 函数x 测试的元素。 def f1(x): return x != 2 print(list(filter(f1, [1, 2, 3]))) def f2(x): return str(x) * 2 print(list(map(f2, [1, 2, 3]))) # lambda 参数列表:lambda print(list(map(lambda x: x * 8, [1, 2, 3]))) f3 = lambda: print("匿名函数") f3() # -----------------------类来了 print(f"{"对象与类":*^100}") # 类是创建对象的蓝图,对象是类的实例。比如类是动物,对象是狗 # 定义类,别忘了,所有的类都是object的直接或者间接子类,建议类名首字母大写 # 当然在父类是object的时候可以省略 class Car(object): #(object)表示继承与object类 # 构造函数__init__:是一个特殊的方法,用于初始化对象的属性。当创建对象时,__init__方法自动调用。 def __init__(self, make, model, year): # self 是一个约定俗成的名字,表示实例对象本身。它是类中的方法的第一个参数,用于访问实例的属性和方法。 self.make = make self.model = model self.year = year def drive(self): print(f"打印{self.make} {self.model} {self.year}") # self可以用来在一个方法中调用同一对象的其他方法。 def f1(self): self.drive() #类体 pass # 通过类创建对象 car = Car("做事", "模型", 18) car.drive() car.f1() # 好好认识类 print(f"----------------------了解完了self后,我们来聊聊,类,真正类") # # 类的成员 # 成员变量(属性):成员变量是类或实例对象的状态(数据)和property这个属性不一样 # 实例变量: # 每个对象独有的变量,通常在构造方法 __init__ 中定义。 # 通过 self 访问和修改。 # 类变量: # 类的所有实例共享的变量,通常在类体内定义。 # 使用类名或 self 访问。 # 构造方法 # 构造方法 __init__ 是类的特殊方法,用于在创建对象时初始化对象的属性。 # 每当类实例化时,__init__ 会自动调用。 # 成员方法:成员方法是定义类的行为的函数。 # 实例方法:绑定到实例,第一个参数是 self,用于访问和修改实例变量。 # 类方法: # 绑定到类,第一个参数是 cls,用于访问和修改类变量。 # 使用 @classmethod 装饰器定义。 # 属性(property) # 属性是类中的特殊成员,用于将方法转换为类似于属性的行为。它使用 @property 装饰器定义,可以通过直接访问的方式获取值,并通过 @property.setter 设置属性值。 print("下面我将用,爸爸,妈妈,儿子,女儿完成类的举例") class dad(object): # 一切类的基类都是object,object是一切类的长辈 out = '你好,这是类变量,在构造函数外定义,通过self在函数内调,当然这是设置好的' # 类变量也要self在类中使用 def __init__(self, lastname, selfme): # init属于构造函数,用于构造类的开始,完成成员变量 self.lastname = lastname # 成员变量,在创建对象时你要填写的要求 self.__selfme = selfme # __名字前有下划线的大概是私有变量或者方法,一般在外无法调用 # 当然其实可以,只不过这样不好,所以大家就普遍这么做了 # 还有一件事,可以通过属性完成对私有变量方法的改变,是p开头的那个 def run(self): # 这是成员函数,就像成员变量一样,可以通过self调用 # 对了,这个也可以私有 print(self.out) def __run1(self): # 如果要修改私有方法怎么办,不可以 # 但是如果私有方法中有本方法外的变量或者函数就可以通过这些修改 print("私有的") def run2(self): self.__run1() # 一般私有的在内部使用,而且最好在公有成员面前使用,在一般不在类方法中用 @classmethod #这是类方法,是的,毕竟有类成员嘛,不要忘了,用这个声明 def c_run1(cls): # 在成员中用self变色这个类,但是在这里,用cls表示 print(cls.out) # 比如这样就可以调用out了 @property #我们该如何访问私有变量,就用他,在写个小函数 def get_selfme(self): return self.__selfme @get_selfme.setter #获取属性函数名.setter就可以设置了 def set_selfme(self, value): self.__selfme = value # 用的时候自己set_selfme="value"就可以了,会自己传入的 # ok一个类的大部分就没有了,说完了 dad1 = dad('叶', "爱了") print(dad1.get_selfme) dad1.set_selfme = "讨厌" print(dad1.get_selfme, dad1.out) dad1.run() dad1.run2() dad1.c_run1() # ok print(f"{"开始多继承":*^100}") class mom: out = "mom" # object为父类时可以省略 def __init__(self, name, lastname): self.name = name self.lastname = lastname class son(mom): def __init__(self, me, name, lastname): super().__init__(name, lastname) # 含有参数的基础 self.me = me son1 = son('son', name="mom", lastname='mom1') print(son1.name) class nv(dad, mom): def __init__(self, lastname, selfme): super().__init__(lastname, selfme) # 注意父类的变量的定义 # 默认靠左优先,比如本例 的dad类 nv1 = nv("ni", "hao") print(nv1.out) # 方法重写 # 在继承了父类的方法后,命名同名方法叫方法重写 # 多肽性 # 多态简单的说就是在继承的时候,对父类的修改细化 # 比如父-动物(方法:有嘴,作用是叫),子-猫(方法:有嘴,作用是喵喵叫),狗(方法:有嘴,作用是咬人和叫) # 多态如何实现: # 1. 方法重写(Overriding) # 子类可以重写(覆盖)父类的方法,以提供不同的实现。在调用方法时,Python 会根据实际的对象类型来选择适当的方法。 # 2. 方法重载(Overloading)简单的说就是,不写参数一种方法,有参数另外一种方法 # class Calculator: # def add(self, a, b, c=0): # return a + b + c # calc = Calculator() # print(calc.add(1, 2)) # 调用 add(1, 2, 0) # print(calc.add(1, 2, 3)) # 调用 add(1, 2, 3) # Python 不直接支持方法重载(即定义多个相同名称但参数不同的方法),但可以使用默认参数或可变参数来模拟重载。 # 3. 操作符重载(Operator Overloading),目前不考虑 # Python 允许你通过定义特殊方法(例如 __add__、__mul__)来重载操作符,使得自定义对象支持常见的操作符。