python面向对象理解

面向对象编程(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并没有对语法严格定义,其实只是给私有属性或方法换了个“名字”来限制访问,“防君子不防小人”,
python面向对象理解_第1张图片

__slots__魔法

在类中定义__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)

python面向对象理解_第2张图片

继承和多态

继承,就是在已有类的基础上创建新类,让一个类从另一个类那里将属性和方法继承下来,不重复造轮子,提供继承信息的类叫做父类,也叫基类或者超类,得到继承信息的类叫做子类,也叫做派生类或衍生类,子类可以在父类的基础上,定义自己的属性和方法,所以子类拥有比父类更多的功能。
在实际使用中,通常用一个子类对象替换掉一个父类对象,对应的原则称为里氏替换原则。
在继承中,如果在子类中直接写构造方法__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())

@property装饰器

直接将属性暴漏给外界是很危险的,不能让外界直接访问,而设为私有属性也存在诸多问题,所有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)

在这里插入图片描述

练习:
python面向对象理解_第3张图片

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__())

python面向对象理解_第4张图片

python面向对象理解_第5张图片

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)

在这里插入图片描述

python面向对象理解_第6张图片

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)

在这里插入图片描述

你可能感兴趣的:(python面向对象理解)