面向对象编程基础
类是对象的蓝图和模板,对象是类的实例
一、定义类(class)
1、最简单的类
#标识 类名 object:python3可写可不写,2必须写
class class_name(object):
print('hello')
if __name__ == "__main__":
Joker = class_name
class class_name(object):
#重写init函数,并不是新的定义,但必须写(当用某些公共变量时在此定义)
def __init__(self):
#初始化,打标记,以便于重复利用
self.a = 1000
#打上self标记表示调用的是自己是“class_name”类的不然不能引用,self是印记的作用,不代表一个参数
def A(self):
print(self.a)
print("sdf dgh htd")
if __name__ == "__main__":
Joker = class_name #相当于走了初始化__init__
Joker.A() #在类中调用使用.
print(Joker.a)
**练习:**打印进度条(每5%出一个#)
import time
class Joker(object):
def jindutiao(self,count):
for i in range(0,100):
time.sleep(0.05)
print('%d%%\r'%(i+1),end = "",flush = True)
if i % 5 == 0:
res = '#'*count
print('%s %d%%\r'%(res,(i + 5)),end = "",flush = True)
count += 1
print()
if __name__ == "__main__":
Joker = Joker()
Joker.jindutiao()
class Joker(object):
def jindutiao(self):
self.count = count
def A(self):
print(self.count)
if __name__ == "__main__":
Joker = Joker() #相当于调用类的初始化
Joker.jindutiao(count = 1)
Joker.A()
二、类传参
class Joker(object):
def __init__(self,num):
self.a = num
print(self.a)
if __name__ == "__main__":
Joker = Joker(10) #可直接调用__init__
#结果:10
**练习:**计算文件中大写字母的数量
class XXX(object):
def __init__(self,path):
self.path = path
self.count = 0
def read(self):
with open('/Users/john/Documents/Python/MEI/test.txt') as f:
lines = f.readlines()
for line in lines:
new_line = line.strp('\n')
for i in new_line:
if i.isupper():
self.count +=1
print('The Upper word is %d'%self.count)
if __name__ == "__main__":
path = '/Users/john/Documents/Python/MEI/test.txt'
xxx = XXX(path)
xxx.read()
三、访问可见性
面向对象编程语言中,我们通常会将对象的属性设置为私有的(private)或受保护的(protected),简单的说就是不允许外界访问,而对象的方法通常都是公开的(public),因为公开的方法就是对象能够接受的消息。在Python中,属性和方法的访问权限只有两种,也就是公开的和私有的,如果希望属性是私有的,在给属性命名时可以用两个下划线作为开头
1、公有变量外部可调用
class class_name:
def __init__(self):
self.a = 1000
def A(self):
print(self.a)
if __name__=="__main__":
name = class_name()
name.A()
print(name.a)
"""
1000
1000
"""
2、私有变量仅内部可调
class class_name:
def __init__(self):
self.__a = 1000
def A(self):
print(self.__a)
if __name__=="__main__":
name = class_name()
name.A()
print(name.a)
#结果:AttributeError: 'class_name' object has no attribute 'a'
3、私有函数内部可调
class class_name:
def __init__(self):
self.__a = 1000
def A(self):
print(self.a)
print(self.__B())
def __B(self):
print('Hello B')
if __name__=="__main__":
name = class_name()
name.A()
#结果:AttributeError: 'class_name' object has no attribute 'a'
4、外部调用私有变量(如果知道更换名字的规则仍然可以访问)
class Joker(object):
def __init__(self):
self.__a = 1000
if __name__=="__main__":
joker = Joker()
joker._Joker__a = 100000
print(joker._Joker__a)
但是不建议将属性设置为私有的,因为这会导致子类无法访问。不过可以属性名以单下划线开头来表示属性是受保护的,本类之外的代码在访问时应该要慎重
面向对象进阶
一、装饰器(@property)
class Joker(object):
def __init__(self):
self.__a = 1000
@property
def look(self):
return self.__a
if __name__ == "__main__":
name = Joker()
#name.look
print(name.look) #函数变成了一个属性self.look
#结果:1000
改变私有变量的输出值
class Joker(object):
def __init__(self):
self.__a = 1000
if __name__ == "__main__":
joker = Joker()
joker.a = 100000
print(joker.a) #函数变成了一个属性self.look
二、类的动态绑定
class Joker(object):
def __init__(self):
self.__a = 1000
if __name__ == "__main__":
joker = Joker()
joker.a = 100000
print(joker.a)
joker.b = 500000 ##
print(joker.b)
#结果:100000
# 500000
三、修改器(更改私有变量)(@a.setter)
class Joker(object):
def __init__(self):
self.__a = 1000
@property #访问器
def a(self):
return self.__a
@a.setter
def a(self,new_num):
self.__a = new_num
if __name__ == "__main__":
joker = Joker()
joker.a = 200000
print(joker.a)
#结果:200000
四、__slots__魔法
限定自定义类型的对象,只对当前类的对象生效,对子类并不起任何作用
class Joker:
__slots__ = ('uuu','hhh')
def __init__(self):
pass
if __name__ == "__main__":
joker = Joker()
joker.uuu = 200000
print(joker.uuu)
#结果:200000
五、静态方法和类方法
class Joker(object):
def __init__(self):
self.a = 10000
def A(self):
print(self.a)
if __name__ == "__main__":
joker = Joker()
joker.A ()
#结果:10000
1、静态方法
class Joker(object):
def __init__(self):
self.a = 10000
@staticmethod
def A(self):
print('hahaha')
if __name__ == "__main__":
joker = Joker()
joker.A ()
还可以在类中定义类方法,类方法的第一个参数约定名为cls,它代表的是当前类相关的信息的对象(类本身也是一个对象,有的地方也称之为类的元数据对象),通过这个参数我们获取和类相关的信息并且可以创建出类的对象
六、继承
**1、**类和类之间的关系有三种:is-a、has-a和use-a(继承、聚合、依赖)
2、继承(单)
一个类从另一个类那里将属性和方法直接继承下来,从而减少重复代码的编写。提供继承信息称之为父类;得到继承信息的称之为子类。子类除了继承父类提供的属性和方法,还可以定义自己特有的属性和方法。
class A(object):
def __init__(self,a1):
self.a = 10000
self.a1 = a1
def A1(self):
print('A1')
class B(A):
def __init__(self,a1):
A.__init__(self,a1) #有没有参数都必须写
pass
def B1(self):
print(self.a1)
if __name__ == "__main__":
b = B('fghj')
b.B1()
#fghj
简化
class A(object):
def __init__(self):
self.a = 10000
def A1(self):
print('A1')
class B(A):
def __init__(self):
A.__init__(self)
pass
def B1(self):
print(self.a)
if __name__ == "__main__":
b = B()
b.B1()
#结果:10000