############### 类的基本操作 ##############
""" 类的基本认识: 1,类就是一个模子 2,dict,list都是类,具体的一个字典和列表就是一个类的实例,就是对象, 3,类定义的时候,类名后面可以有括号,也可以没有括号, 4,类传参是通过__init__方法来传参的,只要实例化一个对象,就会调用这个方法, 5,一个类有三要素:类名,属性,方法,类名要大写,类名使用大驼峰命名法, 6,self代表类的实例,必须要有,名字不必须是self,但是约定俗成就是self """ """ 类的初始化方法(构造方法): 类在实例化的时候,会自动执行以下操作: 1,为对象在内存中分配空间--创建对象 2,为对象的属性设置初始值--初始化方法 这是初始化方法就是 __init__方法,这是对象的内置方法,初始化方法是专门来定义一个类具有哪些属性的方法!!! 如果定义属性? 语法:self.属性名=属性的初始值 第一种:self.name="tom" # 这种就把这个属性固定死了,不好,但是在类中,我们不希望属性固定 第二种:我们可以给函数增加一个形参,用形参来替换被固定死的值, """ class Person: # 类名 country = ‘China‘ # 创造了一个只要是这个类就一定有的属性 # 类属性 静态属性 def __init__(self,*args): # 初始化方法,self是对象,是一个必须传的参数 # self就是一个可以存储很多属性的大字典 self.name = args[0] # 往字典里添加属性的方式发生了一些变化 self.hp = args[1] self.aggr = args[2] self.sex = args[3] def walk(self,n): # 方法,一般情况下必须传self参数,且必须写在第一个 # 后面还可以传其他参数,是自由的 print(‘%s走走走,走了%s步‘%(self.name,n)) # print(Person.country) # 类名 可以查看类中的属性,不需要实例化就可以查看 alex = Person(‘狗剩儿‘,100,1,‘不详‘) # 类名还可以实例化对象,alex对象 # 实例化 print(alex.__dict__) # 查看所有属性 {‘name‘: ‘狗剩儿‘, ‘hp‘: 100, ‘aggr‘: 1, ‘sex‘: ‘不详‘} # print(alex.name) # 查看属性值 # print(alex.hp) # 查看属性值 # alex.walk(5) # Person.walk(alex,5) # 调用方法 类名.方法名(对象名),这是两种调用方法, print(Person.__dict__) # print(Person.__dict__[‘country‘]) # Person.__dict__[‘country‘] = ‘印度‘ # 不能修改, # print(alex.__dict__[‘name‘]) # alex.__dict__[‘name‘] = ‘二哥‘ # print(alex.name) # alex.name = ‘二哥‘ """ # 对象 = 类名() # 过程: # 类名() 首先 会创造出一个对象,创建了一个self变量 # 调用init方法,类名括号里的参数会被这里接收 # 执行init方法 # 返回self # 对象能做的事: # 查看属性 # 调用方法 # __dict__ 对于对象的增删改查操作都可以通过字典的语法进行,但是不这么用, # 类名能做的事: # 实例化 # 调用方法 : 只不过要自己传递self参数 # 调用类中的属性,也就是调用静态属性,只能调用静态属性,动态属性不能调用, # __dict__ 对于类中的名字只能看 不能操作,需要重点记忆, """
############### 类和对象的命名空间 ##############
""" # 类里 可以定义两种属性 # 静态属性 # 动态属性 命名空间的问题: 1,类新建了之后会有一个内存空间, 2,类每次实例化一个都会再开启一个内存空间, 3,为什么静态属性可以实例化对象调用?因为在自己的空间找不到,会去类里面找,这就是原理, 4,注意实例化对象调用修改了这个属性,不会更改类里面的空间的,会在自己实例化对象里面创建一个新的属性,他是没有权限修改类里面的属性的值的, 5,这样会有一个问题,类对象修改了这个静态属性,以后使用都不会变了,你要使用类的就要把自己创建的这个属性删除,del 类实例.静态变量, # 类中的静态变量 可以被对象和类调用 # 对于不可变数据类型来说,类变量最好用类名操作,字符串, # 对于可变数据类型来说,对象名的修改是共享的,类定义了一个静态属性是列表,这个就指向一个内存空间存储着列表, python.language[0]=‘English‘,如果一个对象修改了类的静态属性列表,那就是整个的指向都修改了,会导致所有的实例对象都改动了, python.language=[‘English‘],但是如果重新赋值,就是就是独立的,不会影响到其他的对象获取这个值,是不会改变的,, 导入一个包,就相当于是一个实例化, # 包 —— __init__ # import package —— 类的实例化的过程 # import time # time.time() """ class Course: language = [‘Chinese‘] def __init__(self,teacher,course_name,period,price): self.teacher = teacher self.name = course_name self.period = period self.price = price def func(self): pass # Course.language = ‘English‘ # 通过类名调用静态属性,可以这样修改, # Course.__dict__[‘language‘] = ‘Chinese‘ # 通过类名调用静态属性,但是不能__dict__这么修改, # print(Course.language) python = Course(‘egon‘,‘python‘,‘6 months‘,20000) linux = Course(‘oldboy‘,‘linux‘,‘6 months‘,20000) python.language = ‘‘ # print(python.language) # 类中的静态变量是可以被类和对象调用的, # print(linux.language) # Course.language = ‘Chinese‘ # print(python.language) # print(linux.language) # del python.language # 删除对象里面的静态属性,就可以访问到类里面的静态属性了, # print(python.language) # print(python.__dict__) # print(Course.language) # print(linux.language) # print(linux.__dict__) # 创建一个类,每实例化一个对象就计数 # 最终所有的对象共享这个数据 # class Foo: # count = 0 # def __init__(self): # Foo.count += 1 # 类名操作静态属性,所有的对象都是共享的, # # f1 = Foo() # f2 = Foo() # print(f1.count) # 2 # print(f2.count) # 2 # f3 = Foo() # print(f1.count) # 3 # 认识绑定方法,就是对象调用方法,这个方法就是绑定在这个对象上面了, # def func():pass # print(func) # # class Foo: # def func(self): # print(‘func‘) # def fun1(self): # pass # f1 = Foo() # print(Foo.func) # print(f1.func) # print(f1.fun1) #<bound method Foo.func of f1>
############### 对象之间的交互 ##############
# 对象之间的交互 # 人狗大战 class Dog: def __init__(self,name,aggr,hp,kind): self.name = name self.aggr = aggr # 攻击力 self.hp = hp self.kind = kind def bite(self,person): person.hp -= self.aggr class Person: def __init__(self,name,aggr,hp,sex): self.name = name self.aggr = aggr self.hp = hp self.sex = sex self.money = 0 def attack(self,dog): dog.hp -= self.aggr def get_weapon(self,weapon): if self.money >= weapon.price: self.money -= weapon.price self.weapon = weapon self.aggr += weapon.aggr else: print("余额不足,请先充值") class Weapon: def __init__(self,name,aggr,njd,price): self.name = name self.aggr = aggr self.njd = njd # 耐久度 self.price = price def hand18(self,person): if self.njd > 0: person.hp -= self.aggr * 2 self.njd -= 1 alex = Person(‘alex‘,0.5,100,‘不详‘) jin = Dog(‘金老板‘,100,500,‘teddy‘) w = Weapon(‘打狗棒‘,100,3,998) # alex装备打狗棒 alex.money += 1000 alex.get_weapon(w) print(alex.weapon) print(alex.aggr) alex.attack(jin) print(jin.hp) alex.weapon.hand18(jin) print(jin.hp) # 组合 :就是一个属性的值是一个对象,这就是组合,
############### 单继承 ##############
# class A(object):pass # 父类,基类,超类 # class B:pass # 父类,基类,超类 # class A_son(A,B):pass # 子类,派生类,可以多继承,继承两个类 # class AB_son(A):pass # 子类,派生类 # 一个类 可以被多个类继承 # 一个类 可以继承多个父类 —— 只有在python里,其他语言没有多继承, # print(A_son.__bases__) # __bases__,这是查看继承了谁 # print(AB_son.__bases__) # print(A.__bases__) # python3里面所有的类都有父类,这种就叫做新式类 # 任何没有继承的类都是默认继承了object, # 继承和抽象有密切的关系,比如动物类,狗类,猫类,鸟类,人类,继承就是为了能使得代码简洁, # 单继承,派生属性和派生方法 # 派生方法就是父类没有的方法, # class Animal: # def __init__(self,name,aggr,hp): # self.name = name # self.aggr = aggr # self.hp = hp # # def eat(self): # print(‘吃药回血‘) # self.hp+=100 # def func(self): # print(‘Animal.func‘) # # class Dog(Animal): # def __init__(self,name,aggr,hp,kind): # Animal.__init__(self,name,aggr,hp) # # self.kind = kind # 派生属性 # def eat(self): # Animal.eat(self) # 如果既想实现新的功能也想使用父类原本的功能,还需要在子类中再调用父类 # self.teeth = 2 # def bite(self,person): # 派生方法 # person.hp -= self.aggr # def func(self): # 对父类的重写, # print(‘Dog.func‘) # # jin = Dog(‘金老板‘,100,500,‘吉娃娃‘) # jin.eat() # print(jin.hp) # 父类中没有的属性 在子类中出现 叫做派生属性 # 父类中没有的方法 在子类中出现 叫做派生方法 # 只要是子类的对象调用,子类中有的名字 一定用子类的,子类中没有才找父类的,如果父类也没有报错 # 如果父类 子类都有 用子类的 # 如果还想用父类的,单独调用父类的: # 父类名.方法名 需要自己传self参数 # super().方法名 不需要自己传self # 正常的代码中 单继承 === 减少了代码的重复 # 继承表达的是一种 子类是父类的关系 class Animal: def __init__(self,name,aggr,hp): self.name = name self.aggr = aggr self.hp = hp def eat(self): print(‘吃药回血‘) self.hp+=100 class Dog(Animal): def __init__(self,name,aggr,hp,kind): super().__init__(name,aggr,hp) # 只在新式类中有,python3中所有类都是新式类 self.kind = kind # 派生属性 def eat(self): super().eat() # 这一步就是把父类的代码继承过来了, print(‘dog eating‘) # jin = Dog(‘金老板‘,200,500,‘teddy‘) # print(jin.name) # jin.eat() # super(Dog,jin).eat() """ # 重写父类方法有两种情况: # 第一种情况,覆盖父类的方法 # 如果父类的方法不能满足子类的需要,就需要重写父类的方法 # 怎么实现:定义一个和父类同名的方法,然后自己实现就可以了,调用的时候会调用子类的重写的方法 # 第二种情况:对父类方法进行扩展 # 就是子类方法包含了父类方法的实现,这是在父类的基础上,增加功能, # 怎么实现: # 仍然需要重写父类的方法, # 1,针对子类特有的的需求,编写代码 # 2,使用super调用原本父类中封装的方法 # 3,增加其他子类的代码 """
############### 类的基本操作 ##############
原文地址:https://www.cnblogs.com/andy0816/p/12289761.html
时间: 2024-11-02 21:54:17