多态
class A:
def __init__(self,name):
self._name=name
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name=name
def say_hello(self):
print('hello %s'%self._name)
# 定义一个函数
# 对于say_hello()这个函数来说,只要对象中含有name属性,它就可以作为参数传递
# 这个函数并不会考虑对象的类型,只要有name属性即可
def say_hello2(obj):
print('hello %s'%obj._name)
# 在say_hello_2中我们做了一个类型检查,也就是只有obj是A类型的对象时,才可以正常使用,
# 其他类型的对象都无法使用该函数,这个函数就违反了多态
# 违反了多态的函数,只适用于一种类型的对象,无法处理其他类型对象,这样导致函数的适应性非常的差
# 注意,向isinstance()这种函数,在开发中一般是不会使用的!
def say_hello3(obj):
# 做类型检查
if isinstance(obj , A):
print('你好 %s'%obj.name)
class B:
def __init__(self,name):
self._name=name
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self.name=name
#
def __len__(self):
return 100
class C(B):
pass
a=A('swk')
b=B('zbj')
a.say_hello()
a.say_hello3()
c=C()
c.__len__()
print(c.name)
print(c)
# len()
# 之所以一个对象能通过len()来获取长度,是因为对象中具有一个特殊方法__len__
# 换句话说,只要对象中具有__len__特殊方法,就可以通过len()来获取它的长度
l = [1,2,3,4]
s = 'helloworld'
print(len(b))
print(len(c))
一个对象可以操作不同的形态,例如:人(‘刘德华’)–通过个歌曲–通过明星属性
- 面向对象的三大特征:
封装 – 确保对象中的数据安全
继承 – 保证了对象的可扩展性
多态 – 保证了程序的灵活性
类的属性和方法
class A():
count=10
def __init__(self):
# 实例属性,通过实例对象添加的属性属于实例属性
# 实例属性只能通过实例对象来访问和修改,类对象无法访问修改
self.name = '孙悟空'
# 实例方法
# 在类中定义,以self为第一个参数的方法都是实例方法
# 实例方法在调用时,Python会将调用对象作为self传入
# 实例方法可以通过实例和类去调用
# 当通过实例调用时,会自动将当前调用对象作为self传入
# 当通过类调用时,不会自动传递self,此时我们必须手动传递self
def test(self):
print('这是test方法~~~ ' , self)
# 类方法
# 在类内部使用 @classmethod 来修饰的方法属于类方法
# 类方法的第一个参数是cls,也会被自动传递,cls就是当前的类对象
# 类方法和实例方法的区别,实例方法的第一个参数是self,而类方法的第一个参数是cls
# 类方法可以通过类去调用,也可以通过实例调用,没有区别
@classmethod
def test_2(cls):
print('这是test_2方法,他是一个类方法~~~ ',cls)
print(cls.count)
# 静态方法
# 在类中使用 @staticmethod 来修饰的方法属于静态方法
# 静态方法不需要指定任何的默认参数,静态方法可以通过类和实例去调用
# 静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类中的函数
# 静态方法一般都是一些工具方法,和当前类无关
@staticmethod
def test_3():
print('test_3执行了~~~')
a=A()
print(a.count)#10
print(A.count)#10
#a.A在功能调用上
# 实例属性,通过实例对象添加的属性属于实例属性
# a.count = 10
# A.count = 100
# print('A ,',A.count)
# print('a ,',a.count)
# print('A ,',A.name)
# print('a ,',a.name)
# a.test() 等价于 A.test(a)
# A.test_2() 等价于 a.test_2()
a.count=100
print(a.count)
print(A.count)
垃圾回收
就像我们生活中会产生垃圾一样,程序在运行过程当中也会产生垃圾
程序运行过程中产生的垃圾会影响到程序的运行的运行性能,所以这些垃圾必须被及时清理,没用的东西就是垃圾
在程序中没有被引用的对象就是垃圾,这种垃圾对象过多以后会影响到程序的运行的性能,所以我们必须进行及时的垃圾回收,所谓的垃圾回收就是讲垃圾对象从内存中删除
在Python中有自动的垃圾回收机制,它会自动将这些没有被引用的对象删除,所以我们不用手动处理垃圾回收
class A:
def __init__(self):
self.name = 'A类'
# del是一个特殊方法,它会在对象被垃圾回收前调用
def __del__(self):
print('A()对象被删除了~~~',self)
a = A()
b = a # 又使用一个变量b,来引用a对应的对象
print(a.name)
a = None # 将a设置为了None,此时没有任何的变量对A()对象进行引用,它就是变成了垃圾
b = None
del a
del b
input('回车键退出...')
模块(module)
模块化,模块化指将一个完整的程序分解为一个一个小的模块,通过将模块组合,来搭建出一个完整的程序
不采用模块化,统一将所有的代码编写到一个文件中
采用模块化,将程序分别编写到多个文件中
- 模块化的特点:
① 方便开发–直接提供调用
② 方便维护–动用哪个,维护哪个
③ 模块可以复用!
在Python中一个py文件就是一个模块,要想创建模块,实际上就是创建一个python文件
注意:模块名要符号标识符的规范
- 在一个模块中引入外部模块
① import 模块名 (模块名,就是python文件的名字,注意不要py)
② import 模块名 as 模块别名
-可以引入同一个模块多次,但是模块的实例只会创建一个
-import可以在程序的任意位置调用,但是一般情况下,import语句都会统一写在程序的开头
-在每一个模块内部都有一个__name__属性,通过这个属性可以获取到模块的名字
-__name__属性值为 __main__的模块是主模块,一个程序中只会有一个主模块
主模块就是我们直接通过 python 执行的模块
import test_module as test
# print(test.__name__)
print(__name__)
模块命名规范
1.不能以下划线,数字,特殊字符开头
2.由数字,字母,字符串组成
规范准守Python的class规范和Java的class规范
# import m
# # 访问模块中的变量:模块名.变量名
# # print(m.a , m.b)
# # m.test2()
# p = m.Person()
# print(p.name)
def test2():
print('这是主模块中的test2')
# 也可以只引入模块中的部分内容
# 语法 from 模块名 import 变量,变量....
# from m import Person
# from m import test
# from m import Person,test
# from m import * # 引入到模块中所有内容,一般不会使用
# p1 = Person()
# print(p1)
# test()
# test2()
# 也可以为引入的变量使用别名
# 语法:from 模块名 import 变量 as 别名
# from m import test2 as new_test2
# test2()
# new_test2()
from m import *
# print(_c)
# import xxx
# import xxx as yyy
# from xxx import yyy , zzz , fff
# from xxx import *
# from xxx import yyy as zz