python Day10 类
19 类与对象
### 1.关于面向对象:我们现如今采用的编程方式是面向对象编程
oop:面向对象编程
面向对象编程:是从面向过程发展过来的
面向对象:代码更灵活,更具扩展性,复用性
### 2 类与对象
类就是对现实世界里事物的模拟,用来描述具有相同的属性和方法的对象的集合。
对象是类的实例。
类是抽象的,对象是具体的。
类的组成:属性和方法
3 python 中的类:
1.定义类和使用类:
定义类:用class为关键字
使用类:实例化
# 以人类为例
class Person: #注意冒号,类名首字母大写
#属性:变量
eye = 2
nose = 1
#行为:就是方法
def run(self):
print("能跑")
def sing(self):
print("能唱")
def eat(self):
print("能吃")
#使用类,也叫类的实例化
#实例化=举个例子
p1 = Person()
print(p1.eye)
p1.run()
2 类属性和实例属性
类属性:类变量,这个值在这个类中是共享的
class A:
a = 20
b = 10
def one(self):
print("hello")
print(self.a)
print(A.a)
obj = A()
obj.one()
#hello
#140703449950608
#140703449950608
-
self 代表的是类的实例,代表当前对象的地址,而 self.class 则指向类
class A(): def one(self): print(id(self)) a = A() a.one() print(id(a))
-
self只能在类内部使用
-
它不必被命名为 self,可以随意调用它,但它必须是类中任意函数的首个参数:
实例属性:写在方法里
class A:
eye = 2 #类属性:直接写在类里
def one(self):
self.head = "聪明" #head就是实例属性
print("hello"+self.head)
def two(self):
print(self.head)
obj = A()
obj.one()
print(obj.head)
#print(A.head)报错,因为head属于当前对象,不属于类
3 利用内置函数访问类属性
class A():
id = 10
print(A.id)
#无需实例化,通过类名直接可以访问类属性
#如果实例化,也可以通过对象名访问类属性
-
getattr():获取属性
print(getattr(A,'id')) #可以用类名 print(getattr(obj,'id')) #也可以用对象名
-
hasattr(obj,attr) 判断属性是否在对象里,返回布尔值
print(hasattr(A,'id'))
-
delattr(class,attr) 删除属性 不能使用对象名,只能用类名
delattr(A,'id')
-
setattr(obj,attr,value) 设置属性,有则修改,无则添加
setattr(A,'id',20)
4 类中的构造方法和析构方法
构造方法:
__init__该方法的特点:无需调用,自动执行
调用:类被实例化的时候自动调用
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
obj = Person("张三")
print(obj.name)
#构造函数的作用是为了赋初值
析构方法:
_del_ 该方法的特点:无需调用,自动执行
调用:在对象被销毁的时候,析构方法自动调用
解释:python使用了引用计数这一简单技术来跟踪和回收垃圾,在python内部记录着所有使用中的对象各有多少引用,当对象被创建时,就创建了一个引用计数,当着这个对象不再被需要时,也就是引用计数变成0时,python内部就会在适当时机进行垃圾回收。
class A:
def __init__(self):
print("构造方法")
def one(self):
print("普通方法")
def __del__(self):
print("析构方法")
obj = A()
obj.one()#构造方法#普通方法#析构方法
作用:主要用于资源释放
#文件IO资源,数据库连接资源,打印机
类中的方法
1)普通方法:
方法跟定义函数一样的格式,只是该函数写在类中
函数=方法
理解:函数是代码块,就是一堆特定代码封装,而类是把一堆变量和函数封装了
也可以传值
调用需要对象调用
2)私有方法:
访问限制:
加单下划线:表示保护,在子类,当前文件,类内部
加双下划线:表示私有,类内部访问
class A:
a = 10
_b = 20
__c = 30
def one(self):
print(self.a)
print(self._b)
print(self.__c)
A().one()
print(A.a)
print(A._b)
#调用私有方法
class A:
def one(self):
print("普通方法")
print(self._two())
print(self.__three())
def _two(self):
return "保护方法"
def __three(self):
return "私有方法"
obj = A()
print(obj._A__three())
#硬整print(obj.func()) #扩大作用域
3)属性方法:将方法转为属性
注解关键字:@property()
class Student:
def __init__(self):
self.__age=0
@property
def age(self):
return self.__age
@age.setter
def age(self, newage):
if newage >= 0 and newage <= 130:
self.__age = newage
else:
print("年龄不符合要求")
s1 = Student()
s1.age = 20
print(s1.age)
4)静态方法
静态方法:通过类名直接调用,不需要创建对象,不会隐式传递self
class A:
a = 10
def __init__(self):
self.b = 20 #实例属性
def two(self):
print("普通方法") #普通方法=实例方法
@staticmethod
def one(): #静态方法
print("hello")
print(A.a)
#print(self.b)报错无法使用self
#self.two()报错无法使用self
@staticmethod
def three():
A.one() #静态方法可以调用静态方法#静态方法的调用A.one()#直接调用A().three()#实例化调用
特点:
静态方法需要加上注解:@staticmethod
静态方法属于类,可以通过类名直接调用
静态方法无法使用self
静态方法只能访问类属性
静态方法可以调用静态方法
5)类方法
类方法,方法的cls是类本身,
注解:@classmethod
class A:
x = "100"
y = None
def __init__(self):
self.y = '200'
@classmethod
def one(cls,ls):
print('hello')
print(ls)
print(cls.y) #输出的是类属性,并不是实例属
A.one()
a = A()
a.one([1,2,2,3])
5 类的继承
类和类之间有继承关系。
子类(派生类 DerivedClaame)会继承父类(基类 BaseClassName)的属性和方法。
继承就是完成了共性抽取,提高代码复用和效率。
class Fu:
a = 10
def one(self):
print("普通方法")
def _two(self):
print("保护方法")
def __three(self): #私有方法无法继承
print("私有方法")class Zi(Fu):
def fun(self):
return self.__three()
obj = Zi()
obj.one()
obj._two()# obj.__three() 报错,私有方法无法继承#
obj.fun() 报错,私有方法无法继承
class People: #定义基本属性
name = ""
age=0 #定义私有属性
__weight = 0
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print(f"我叫{self.name},{self.age}岁")
class Student(People):
grade = ''
def __init__(self,n,a,w,g):
People.__init__(self,n,a,w)
self.grade = g
def speak(self):
print(f"我叫{self.name},{self.age}岁,上{self.grade}年级")
s1 = Student("阿松大",13,50,'五')
s1.speak()
自定义的类默认继承object类
6 类的组合
在一个类中,以另外一个类的对象作为属性,称为类的组合
class A:
def one(self):
print("aasdasdassdas")
class B:
a = A()
obj = B()
obj.a.one()
7 方法重写
当我们调用一个对象,会先在当前对象里寻找,没有则去父类中,还没有就继续往上直到object
重写:有继承关系,子类中重新定义和父类的方法同名产生覆盖
class Animal:
def run(self):
print("动物会跑")
def sleep(self):
print("动物睡觉")
class Dog(Animal):
def run(self):
print("狗跑了")
obj = Dog()
obj.run()
obj.sleep()###狗跑了#动物睡觉
super().fuction():调用父类中被重写的函数
class Animal:
def run(self):
print("动物会跑")
def sleep(self):
print("动物睡觉")
class Dog(Animal):
def run(self):
print("狗跑了")
super().run()
obj = Dog()
obj.run()
obj.sleep()
调用被重写的构造函数
使用 super() 函数
Python 还有一个 super() 函数,它会使子类从其父继承所有方法和属性(不包括私有):
class Student(Person):
def __init__(self, fname, lname):
super().__init__(fname, lname)#不需要写父类名,自动继承父类所有方法和属性
8 抽象类和抽象方法
抽象类:有抽象方法的类,就叫抽象类
抽象方法:当一个方法不确定该如何实现的时候用abc模块定义问抽象方法
import abc#定义抽象类
class Animal(metaclass=abc.ABCMeta): #定义抽象方法
@abc.abstractmethod
def cry(self):
pass #也可以定义普通方法
def one(self):
print("hello")抽象类中有抽象方法的话,不能直接实例化必须用另外一个类去继承抽象类,且必须实现里面的抽象方法方法重写class dog(Animal):
def __init__(self):
pass
def cry(self):
print(1)
d = dog()
d.cry()
d.one()
1)抽象类不能被实例化,只能被继承
2)继承抽象类的类,要实现里面的所有抽象方法
3)当抽象类继承抽象类的时候,里面的抽象方法可以不实现
4)抽象类可以没有抽象方法,有抽象方法的类可能是抽象类
5)没有抽象方法的抽象类,可以被实例化
if _name_ == “__main__”:
判断是否是本文件执行