Python心得
1、 super().属性
在子类派生的新方法中重用父类功能的方式二
- 方式:调用super(自己的类名,self)会返回一个特殊的对象,super(自己的类名,self).属性,会参照当前类的mro列表去父类中查找属性
- 特点:严格依赖于继承关系
示例:
class OldboyPeople:
school = "oldboy"
# 空对象,"艾利克斯",73,'male'
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
def f1(self):
print('1111111')
class Student(OldboyPeople):
def __init__(self,name,age,gender,stu_id,course):
# OldboyPeople.__init__(self,name,age,gender) # OldboyPeople.__init__(空对象,"艾利克斯",73,'male')
super(Student,self).__init__(name,age,gender)
self.stu_id = stu_id
self.course = course
def choose(self):
print('%s 正在选课' %self.name)
def f1(self):
# OldboyPeople.f1(self)
super().f1()
print("22222")
class Teacher(OldboyPeople):
def __init__(self,name,age,gender,salary,level):
OldboyPeople.__init__( self,name,age,gender)
self.salary = salary
self.level = level
def score(self,stu,num):
stu.num = num
print(Student.mro())
stu1=Student("艾利克斯",73,'male',1001,"python全栈开放")
tea1=Teacher("egon",18,'male',2000,10)
print(stu1.__dict__)
print(tea1.__dict__)
stu1.f1()
tea1.score(stu1,99)
print(stu1.num)
结果:
[<class '__main__.Student'>, <class '__main__.OldboyPeople'>, <class 'object'>]
{'name': '艾利克斯', 'age': 73, 'gender': 'male', 'stu_id': 1001, 'course': 'python全栈开放'}
{'name': 'egon', 'age': 18, 'gender': 'male', 'salary': 2000, 'level': 10}
1111111
22222
99
由结果我们可以看出,我们利用super()用法的时候,和我们之前使用直接调用类去使用效果是一样的,但是我们需要注意,在super()用法中可以自动传参,所以我们会方便很多。
2、组合
在学习组合之前我们先来回顾一下,上一篇博客中所说道的 is-a
继承is-a:表示的是,是什么,比如说人是动物,老虎也是动物,飞机是交通工具,汽车也是交通工具,所以is-a表达的就是==“是”==这么一个关系
那么我们现在来讲一下组合是什么吧。
组合:has-a:表示的是以种有的关系,比如说人有睡觉这个能力,老虎也有睡觉这个能力,飞机有飞行的这个能力,直升机也有飞行的能力,所以我们has-a所表示的就是==”有“==的一种关系
那我们再来说组合是什么呢?
组合:把另外一个类的对象赋值给当前对象的属性
记下来我们放出示例给大家看。
示例:
class OldboyPeople:
school = "oldboy"
def __init__(self,name,age,gender):
self.name = name
self.age = age
self.gender = gender
class Teacher(OldboyPeople):
def __init__(self, name, age, gender, level):
super().__init__(name,age,gender)
self.level = level
def tell(self):
print("%s:%s" % (self.name, self.age))
class Student(OldboyPeople):
def __init__(self, name, age, gender):
super().__init__(name,age,gender)
class Course:
def __init__(self, name, price, period):
self.name = name
self.price = price
self.period = period
def tell(self):
print('<%s:%s:%s>' % (self.name, self.price, self.period))
tea1 = Teacher("egon", 18, "male", 10)
stu1 = Student("米奇", 19, "male")
python = Course("python开放", 30000, "3mons")
linux = Course("linux课程", 30000, "3mons")
tea1.courses = [python,linux] #把 课程的对象给到 学生对像下面。
stu1.course = python #把 课程的对象给到 老师对想下面。
# tea,stu # 我们将这两个对象,称为超级对象
stu1.course.tell()
tea1.tell()
for course_obj in tea1.courses:
course_obj.tell()
结果:
<python开放:30000:3mons>
egon:18
<python开放:30000:3mons>
<linux课程:30000:3mons>
3、多态
1. 什么是多态
同一种事物有多种形态
- 例如:动物这种事物有多种形态,如人狗猪
- 特性: 我们可以在不考虑某一个对象具体类型的前提下,直接使用该对象
# 父类有的功能,子类一定有
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def speak(self):
pass
@abc.abstractmethod
def run(self):
pass
# Animal() # Animal的作用是用来制定标准的
class People(Animal):
def speak(self):
print("啊啊啊啊")
def run(self):
print("咻咻咻...")
class Dog(Animal):
def speak(self):
print("汪汪汪")
def run(self):
print("狂奔...")
class Pig(Animal):
def speak(self):
print("哼哼哼")
def run(self):
print("咣咣咣...")
peo1=People()
d1=Dog()
p1=Pig()
peo1.speak()
peo1.run()
d1.speak()
d1.run()
p1.speak()
p1.run()
结果
啊啊啊啊
咻咻咻...
汪汪汪
狂奔...
哼哼哼
咣咣咣...
以上调用abc模块的方法我们称之为,定死指定对象方法,子类中必须要有父类指定的方法,并且方法名字必须与父类的对应。
那接下来我们就使用我们的
2. 鸭子类型:duck
示例:
class People:
def speak(self):
print("啊啊啊啊")
def run(self):
print("咻咻咻...")
class Dog:
def speak(self):
print("汪汪汪")
def run(self):
print("狂奔...")
class Pig:
def speak(self):
print("哼哼")
def run(self):
print("咣咣咣...")
peo1=People()
d1=Dog()
p1=Pig()
peo1.run()
d1.run()
p1.run()
结果:
咻咻咻...
狂奔...
咣咣咣...
上述方法我们直接不用继承去使用,就约定俗成的使用函数方法。
这个我们称之为鸭子类型。
博客园:多态讲解:egon
https://www.cnblogs.com/linhaifeng/articles/7340687.html
4、一切皆为对象
我们直接用示例来演示。
x = 11 # x=int(11)
print(int)
class Foo:
pass
print(Foo)
结果:
<class 'int'>
<class '__main__.Foo'>
通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
5、面向对象高级
我们直接用示例来说。
x = 111 #判断是不是子类
print(type(x) is int)
print(isinstance(x,int))
class Bar:
pass
class Foo(Bar):
pass
print(issubclass(Foo,Bar))
结果:
True
True
True
6、内置方法
我们需要注意:
内置方法都是在满足某种条件下自动触发的
示例:
# 1 __str__
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return f'{self.name}:{self.age}'
stu_obj=Student('egon',18)
print(stu_obj) # print(obj.__str__())
结果:
egon:18
示例2.1:在程序运行结束之前 调用del去删除。
class People:
def __init__(self, name, age,f):
self.name = name
self.age = age
self.f = f
def __del__(self):
print('===>')
# 回收资源
self.f.close()
obj = People("egon", 18,open("a.txt",'w',encoding='utf-8'))
del obj
print('运行完毕...')
结果:
===>
运行完毕...
示例2.1:在程序运行结束之后,系统会自动清理垃圾。
class People:
def __init__(self, name, age,f):
self.name = name
self.age = age
self.f = f
def __del__(self):
print('===>')
# 回收资源
self.f.close()
obj = People("egon", 18,open("a.txt",'w',encoding='utf-8'))
# del obj
print('运行完毕...')
结果:
运行完毕...
===>
7、反射
1.dir(对象)
class Foo:
def __init__(self, x, y):
self.x = x
self.y = y
def f1(self):
print('from f1')
obj = Foo(11, 22)
res = dir(obj)
print(res)
结果:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'f1', 'x', 'y'
会打印出对象所有可以点出来的东西。
2.hasattr getattr setattr delattr
通过字符串来操作对象的属性,这就涉及到内置函数hasattr、getattr、setattr、delattr的使用了(Python中一切皆对象,类和对象都可以被这四个函数操作,用法一样)
class Teacher:
def __init__(self,full_name):
self.full_name =full_name
t=Teacher('Egon Lin')
# hasattr(object,'name')
hasattr(t,'full_name') # 按字符串'full_name'判断有无属性t.full_name
# getattr(object, 'name', default=None)
getattr(t,'full_name',None) # 等同于t.full_name,不存在该属性则返回默认值None
# setattr(x, 'y', v)
setattr(t,'age',18) # 等同于t.age=18
# delattr(x, 'y')
delattr(t,'age') # 等同于del t.age