面向对象编程(Object Oriented Programming-OOP) 是一种解决软件复用的设计和编程方法。 这种方法把软件系统中相近相似的操作逻辑和操作 应用数据、状态,以类的型式描述出来,以对象实例的形式在软件系统中复用,以达到提高软件开发效率的作用。
类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
局部变量:定义在方法中的变量,只作用于当前实例的类。
实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
类是抽象的模板,而实例是根据类创建出来的一个个具体的“对象”,每个对象都拥有相同的方法,但各自的数据可能不同。
在python中,通过class关键字定义类:
class Student:
def __init__(self, name, age):
self.name=name
self.age=age
def diff(self):
print("%s 正在学习" %(self.name))
写在类中的函数,通常称之为(对象的)方法,这些方法就是对象可以接收的消息。
_init__是一个特殊方法用于在创建对象时进行初始化操作,通过该方法可以在创建对象时进行初始化操作,绑定属性
当好一个类后,可以对该类创建对象,使用方法。
student=Student("lh",20)
student.diff()
在很多面向对象编程语言中,我们通常会将对象的属性设置为私有的(private)或受保护的(protected),简单的说就是不允许外界访问,而对象的方法通常都是公开的(public),因为公开的方法就是对象能够接受的消息。在Python中,属性和方法的访问权限只有两种,也就是公开的和私有的,如果希望属性是私有的,在给属性命名时可以用两个下划线作为开头。
class Student:
def __init__(self, name, age):
self.__name=name
self.__age=age
def diff(self):
print("%s 正在学习" %(self.name))
这样,在使用self.name访问变量时,就会报错。
但是在底层的实现原理上python并没有对语法严格定义,其实只是给私有属性或方法换了个“名字”来限制访问,“防君子不防小人”,
在类中定义__slots__变量可以限定自定义类型的对象只能绑定某些属性。
需要说明的是,__slots__的限定只对类的当前对象生效,对子类并不起作用。
class student:
__slots__ = ("name","age")
def __init__(self,name,age,gender):
self.name=name
self.age=age
st=student("lh",20,"男")
print(st.gender)
继承,就是在已有类的基础上创建新类,让一个类从另一个类那里将属性和方法继承下来,不重复造轮子,提供继承信息的类叫做父类,也叫基类或者超类,得到继承信息的类叫做子类,也叫做派生类或衍生类,子类可以在父类的基础上,定义自己的属性和方法,所以子类拥有比父类更多的功能。
在实际使用中,通常用一个子类对象替换掉一个父类对象,对应的原则称为里氏替换原则。
在继承中,如果在子类中直接写构造方法__init__,相当于重构构造函数
如果想继承父类的构造方法,可以用 父类名.__init() 或者 super 继承
如果子类定义了自己的初始化函数,那
class Person:
def __init__(self,name,age):
self.__name = name
self.__age = age
def name(self):
return self.__name()
def age(self):
return self.__age()
def study(self):
print("%s %d岁 正在学习" %(self.__name,self.__age))
class student(Person):
def __init__(self,name,age,score):
super(Person).__init__()
self.score=score
def study(self):
print("%s 正在看动画片" %(self.name))
stu=student("lh",20,100)
print(stu.study())
直接将属性暴漏给外界是很危险的,不能让外界直接访问,而设为私有属性也存在诸多问题,所有Python中有一个解决办法:
使用@property包装器来包装getter和setter方法访问属性的getter(访问器)和setter(修改器)方法进行对应的操作。
@property装饰器可以把类的方法伪装成属性调用的方式。
class student:
def __init__(self,name,age):
self.__name=name
self.__age=age
#访问器—getter方法
@property
def study(self):
print("%s 正在学习" %(self.__name))
@property
def age(self):
return self.__age
@age.setter
def age(self,age):
self.__age=age
stu=student("lh",20)
stu.age=18
print(stu.age)
伪装以后调用方式,就像变量赋值一样,但实际执行的还是函数中的代码,也就是stu.age(18)
@property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。
实例属性的个数取决于实例化对象的个数,每个实例属性都在内存中拥有单独的地址空间。
类属性就是类对象所拥有的属性,相当于类中的全局变量,它被所有类对象的实例对象所共有,在内存中只存在一个副本。
class test:
number=50
def __init__(self):
self.x=20
self.y=30
test1=test()
test2=test()
print(id(test1.number))
print(id(test2.number))
静态方法在使用时在方法前加@staticmethod装饰器。
静态方法与普通方法的区别:静态方法不需要,也不能传入实例参数,类变量。
class test:
@staticmethod
def static_method(*mix):
return mix
class son_test(test):
@staticmethod
def static_method(*mix):
return sum(mix)
sonclass=son_test()
s=sonclass.static_method(15,36,55,20)
print(s)
类方法是将类本身作为对象进行操作的方法。假设有个方法,且这个方法在逻辑上采用类本身作为对象来调用更合理,那么这个方法就可以定义为类方法。另外,如果需要继承,也可以定义为类方法。
类方法只能访问类变量,不能访问实例变量。
class Date(object):
# 魔术方法(构造方法)
def __init__(self, year=2019, month=6, day=16):
self.year = year
self.month = month
self.day = day
# 实例方法
def echo(self):
print("%s-%s-%s" % (self.year, self.month, self.day))
@classmethod
def as_string(cls, str):
month, day, year = str.split('/')
d1 = cls(year, month, day)
return d1
str = '6/19/2019'
d1 = Date.as_string(str)
d1.echo()
顾名思义,就是一个类只能创建一个实例化对象,这在实际应用中非常有意义。
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
用装饰器实现单例模式:
def singleton(cls):
"""
用来装饰类的装饰器: 实例化类时, 只实例化一个对象;
"""
# 初始化一个字典instances, key: 类名 , value: 类实例化的对象
instances = {}
def wrapper(*args, **kwargs):
"""
如果类在缓存instances存在时, 直接返回类对应的对象;
如果类不在缓存instances存在时, 先实例化对象, 将类名和对象名存储到缓存中instances;
"""
if cls in instances:
return instances[cls]
else:
# instances[cls] = cls(*args, **kwargs)
obj = cls(*args, **kwargs)
instances[cls] = obj
return obj
return wrapper
@singleton # @single =====> Student = singleton(Student)
class Student(object):
pass
# # 如果类没有被装饰器sigleton装饰的化, 返回的s1和s2时两个不同的对象(内存地址不同);
# s1 = Student()
# s2 = Student()
# print(s1, s2)
# 如果类有被装饰器sigleton装饰, 返回的s1和s2时两个相同的对象(内存地址相同);
s1 = Student()
s2 = Student()
print(s1, s2)
class quene:
def __init__(self):
self.__quene=[]
def push(self,x):
self.__quene.append(x)
print(self.__quene)
def pop(self):
if self.empty()==True:
self.__quene.pop(0)
return self.__quene
else:
print("队列为空")
def __len__(self):
return len(self.__quene)
def empty(self):
if self.__len__()!=0:
return True
else:
return False
que=quene()
que.push(50)
que.pop()
print(que.__len__())
lee=[15,25,2,8,35]
oushu=[item for item in lee if item%2==0]
jishu=[item for item in lee if item%2!=0]
result=oushu+jishu
print(result)
keyboard={"2":"abc","3":"def","4":"ghi","5":"jkl","6":"mno","7":"pqrs","8":"tuv","9":"wxyz"}
str=input("please input str:")
res=[""]
for key in str:
tmp=[]
if key in str:
for item in keyboard.get(key):
for r in res:
tmp.append(r+item)
res=tmp
print(res)