Python入门-面向对象

1.面向对象的产生背景

  • 面向过程:根据业务逻辑从上到下写垒代码,12345的先后顺序
  • 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
  • 面向对象:对函数进行分类和封装,让开发“更快更好更强...”
#面向过程,代码如下:根据具体业务问题,做出对应处理====================================================  
while True:
  if cpu利用率 > 90%:
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接
 
    if 硬盘使用空间 > 90%:
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接
 
    if 内存占用 > 80%:
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接
#函数式编程,代码如下:发送邮件功能重复使用,提取出来作为一个工具,反复调用函数即可==============================
def 发送邮件(内容):
    #这是一个发送邮件函数
    连接邮箱服务器
    发送邮件
    关闭连接
 
while True:
    if cpu利用率 > 90%:
        发送邮件('CPU报警')
    if 硬盘使用空间 > 90%:
        发送邮件('硬盘报警')
    if 内存占用 > 80%:
        发送邮件('内存报警') 

通过上面的代码可以看出:

面向过程的程序设计的核心是过程(流水线式思维),而过程就是解决问题的步骤,

面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西。

  • 优点是:极大的降低了写程序的复杂度,只需要顺着要执行的步骤,堆叠代码即可。
  • 缺点是:灵活性很低,一套流水线或者流程就是用来解决一个问题,代码牵一发而动全身。

2.面向对象编程的创建

面向对象编程(Object Oriented Programming,OOP,面向对象程序设计),面向对象编程是一种编程方式。此编程方式的落地需要使用 “类” 和 “对象” 来实现,所以,面向对象编程其实就是对 “类” 和 “对象” 的使用。

  • class是关键字,表示类
  • 创建对象,类名称后加括号即可
# 创建第一个类,class是关键字,表示类
class Foo:  
    """
    这是一个简单的类,有两个方法
    """
    def hello(self):   #类中的函数叫做“方法”,第一个参数必须是self,关于self后面再解释
        print("hello")
    def word(self):
        print("word")
# 根据类Foo类,创建对象obj
obj = Foo()  # 创建对象,类名称后加括号即可
obj.hello()  # 执行Bar方法
obj.word()   # 执行Hello方法 
"""
hello
word
"""

3.类属性,实例属性和私有属性

 

class User:
    age = "88" #类属性,直接定义
    def __init__(self, birthday):
        self.__birthday = birthday#实例属性,也是私有属性,有 _ _ 标识
    def get_age(self):
        return 2022 - self.__birthday #只能通过公共方法,访问私有属性
class Stu(User):
    def __init__(self,birthday):
        self.__birthday= birthday#实例属性,创建对象,实例化时,必须给定值
if __name__ == '__main__':
    user = User(1993)
    print(user.get_age())
    print(user._User__birthday) #私有属性的强制访问
    print(user._Stu__birthday)  #私有属性相同情况下,不影响互相访问

 

4.面向对象优点

对比函数的优点

# 函数式编程和面向对象编程,执行函数方式的不同:
    面向对象:【创建对象】【通过对象执行方法】
    函数编程:【执行函数】
# 应用场景不同,选择不同的方法:
    函数式的应用场景 --> 各个函数之间是独立且无共用的数据
    面向对象的应用场景各个函数间是有互相关联的

对比面向过程的优点

#解决了程序的扩展性。

面向对象编程可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容。

了解一些名词:类、对象、实例、实例化

类:具有相同特征的一类事物(人、狗、老虎)

对象/实例:具体的某一个事物(隔壁阿花、楼下旺财)

实例化:类——>对象的过程(这在生活中表现的不明显,我们在后面再慢慢解释)

5.面向对象三大特性

面向对象的三大特性是指:封装、继承和多态。学会了三大特性,面向对象也就OK了。

 

6.python一切皆对象

函数和类也是对象,属于python的一等公民
#1.函数和类都可以赋值给一个变量
def hello(name="ok"):
    print("hello word")
class He:
    def __init__(self):
        print("ok")
a = hello
a()
b= He
b()

#2.函数和类都可以添加到集合对象中
obj_list = []
obj_list.append(hello)
obj_list.append(He)
for i in obj_list:
    print(i())


#3.一个函数可以作为参数传递给另一个函数
def haode():
    print("start")
    return hello
c = haode()

#4.一个函数可以当做某一个函数的返回值
c("tom")

 7.为什么一切皆对象

a = 1
b = "abc"

print(type(1)) #<class 'int'>
print(type(a)) #<class 'int'>
print(type(int)) #<class 'type'>
print(type(b))   #<class 'str'>
print(type(str)) #<class 'type'>
c=[1,2]
print(type(c))     #<class 'list'>
print(type(list))  #<class 'type'>
"""
type->int->1
type->list->[1,2]
type->class->obj

"""

class Hello(object):
    pass
he = Hello()
print(type(he))   #<class '__main__.Stu'>
print(type(Hello))#<class 'type'>
print(Hello.__base__) #<class 'object'>
"""
#object是顶层基类,
"""
print(type.__base__)#<class 'object'>,type是一个类,继承于基类
print(type(object)) #<class 'type'>,object指向type类
print(object.__base__) #None
print(object.__bases__) #()

#包括object以及全部的数据类型,都是type的实例,type也是自身的实例,自己指向自己,所以一切皆对象
#包括type以及全部的数据类型,都是继承于object,全部都是object的基类,一切都是继承object

 

 8.类的魔法函数

魔法函数可以增强类的功能

#没有魔法函数,去遍历对象========================================================================
class Comany:
    def __init__(self, employee_list:list):
        self.employee = employee_list
com = Comany(["tom","jack","alice"])
emp = com.employee
for i in emp:
    print(i)

#有魔法函数,去遍历对象==========================================================================
class Comany:
    def __init__(self, employee_list:list):
        self.employee = employee_list
    #双下划线开头和结尾的方法
    def __getitem__(self, item):
        return self.employee[item]
com = Comany(["tom","jack","alice"])
#可以直接迭代遍历类对象
for i in com:
    print(i)

#有魔法函数,实现切片==========================================================================
class Comany:
    def __init__(self, employee_list:list):
        self.employee = employee_list

    #双下划线开头和结尾的方法
    def __getitem__(self, item):
        return self.employee[item]
com = Comany(["tom","jack","alice"])
com2 = com[:2]
for i in com2:
    print(i)

#有魔法函数,实现直接len方法====================================================================
class Comany:
    def __init__(self, employee_list:list):
        self.employee = employee_list
    def __len__(self):
        return len(self.employee)

com = Comany(["tom","jack","alice"])
print(len(com))

 str和repr

class Comany:#===========================================================================
    def __init__(self, employee_list:list):
        self.employee = employee_list
com = Comany(["tom","jack","alice"])
print(com)   
print(str(com))
"""
<__main__.Comany object at 0x000001780F6FF700>
<__main__.Comany object at 0x000001780F6FF700>
"""

class Comany:#有str方法,会直接调用str方法====================================================
    def __init__(self, employee_list:list):
        self.employee = employee_list
    def __str__(self):
        return ",".join(self.employee)
com = Comany(["tom","jack","alice"])
print(com)
com
"""
tom,jack,alice
<__main__.Comany at 0x1780f6fe8c0>
"""

class Comany:#先使用repr方法,repr方法再去调用str方法===========================================
    def __init__(self, employee_list:list):
        self.employee = employee_list
    def __str__(self):
        return ",".join(self.employee)
    def __repr__(self):
        return ",".join(self.employee)
com = Comany(["tom","jack","alice"])
print(com)
com
"""
tom,jack,alice
tom,jack,alice
"""

add方法

class Myvector(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def __add__(self, other):
        res = Myvector(self.x+other.x, self.y+other.y)
        return res
    def __str__(self):
        return f"x:{self.x}, y:{self.y}"
my = Myvector(1,2)
second = Myvector(2,3)
print(my+ second) #x:3, y:5

 isinstance和type的区别使用-推荐用isinstance

class A:
    pass
class B(A):
    pass

b = B()
print(isinstance(b,B))#True
print(isinstance(b,A))#True

print(type(B))#<class 'type'>
print(type(b))#<class '__main__.B'>
print(B)      #<class '__main__.B'>
print(type(b) is B)#True

print(A) #<class '__main__.A'>
print(type(b) is A) #False

 类属性和实例属性

class A:
    aa = 1
    def __init__(self, x, y):
        self.x = x
        self.y = y

a = A(2,3) #实例化对象
print(a.aa)
print(a.x)
print(a.y)
print(A.aa)
print(A.x)#类属性没有x,会报错:AttributeError: type object 'A' has no attribute 'x'

#类属性修改,实例属性跟着修改
A.aa = 11
print(a.aa)
print(A.aa)
#实例对象修改了实例属性,类属性不变
a.aa = 99
print(A.aa)
print(a.aa)

查看类的全部属性__dict__和dir

#python的自省机制:通过一定的机制,查询到对象的内部结构

class Person:
    """
    人类
    """
    name = "user"

class Stu(Person):
    def __init__(self, school):
        self.school = school

if __name__ == '__main__':
    user = Stu("北京大学")
    print(user.__dict__) #可以获取类的全部属性:{'school': '北京大学'}
    print(user.name)     #user,向上查找,[<class '__main__.Stu'>, <class '__main__.Person'>, <class 'object'>]
    print(Person.__dict__)#{'__module__': '__main__', 'name': 'user', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None}
    user.__dict__["test"] = "test" #自定义,设置属性
    print(user.__dict__)#{'school': '北京大学', 'test': 'test'}
    print(dir(user))#['__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__', 'name', 'school', 'test']
    #dir方法比——dict——方法,更加详细

 

类方法,静态方法,实例方法

class Date:
    def __init__(self, year, mouth, day):
        self.year = year
        self.day = day
        self.mouth = mouth
    def __str__(self):
        return f"{self.year}-{self.mouth}-{self.day}"

    def tomorrow(self):
        self.day += 1

    @staticmethod
    def parse_string(date_str):
        year, mouth, day = tuple(day_str.split("-"))
        return Date(year, mouth, day) #类名保持一致,硬编码
    @classmethod
    def from_string(cls, date_str):
        year, mouth, day = tuple(day_str.split("-"))
        return cls(year, mouth, day)  #类名随意更改不受影响,
       #return cls(year, mouth, day)  #cls只是关键字,可以改为self也完全可以

    @staticmethod
    def is_str(daye_str):
        """
        判断是否字符串
        """
        year, mouth, day = tuple(day_str.split("-"))
        if int(year)>0 and int(mouth) <13 and int(day) <31:
            return True
        return False #静态方法,不需要self参数
    @property
    def pro_str(self):
        day_str = "2099-12-12"
        year, mouth, day = tuple(day_str.split("-"))
        return year, mouth, day
if __name__ == '__main__':
    day = Date(2022, 8, 8)
    print(day)
    day.tomorrow()
    print(day)
    day_str = "2099-12-12"
    #使用staticmethod完成初始化
    new_day = Date.parse_string(day_str)
    print(new_day)
    new_day = Date.from_string(day_str)
    print(new_day)
    new_day = Date.is_str(day_str)
    print(new_day)
    new_day = day.pro_str#可以直接当成属性使用
    print(new_day)

 从面向对象角度理解数据类型

# 1.各种数据类型,都是类
# 2.数据类型的方法,都是类的实例方法
    def append(self, item):
        self.data.append(item)

    def insert(self, i, item):
        self.data.insert(i, item)

    def pop(self, i=-1):
        return self.data.pop(i)

    def remove(self, item):
        self.data.remove(item)

    def clear(self):
        self.data.clear()

    def copy(self):
        return self.__class__(self)

    def count(self, item):
        return self.data.count(item)

    def index(self, item, *args):
        return self.data.index(item, *args)

    def reverse(self):
        self.data.reverse()

 列表的隐藏方法

#列表的+=方法,和extend方法,append方法
a = [1,23]
c = a + [3,4]
print(c) #[1, 23, 3, 4]
c += (88,99)
print(c)#[1, 23, 3, 4, 88, 99],等于调用extend方法
c.extend((4,5,9))
print(c)#[1, 23, 3, 4, 88, 99, 4, 5, 9]
c.extend(range(8))#放可迭代类型都可以
print(c)#[1, 23, 3, 4, 88, 99, 4, 5, 9, 0, 1, 2, 3, 4, 5, 6, 7]

列表高级切片用法

#切片会返回新的列表对象,而不会更改原有列表

print(list(range(101))[::2]) # 返回偶数
print(list(range(101))[1::2])# 返回奇数

c[len(c):] = [111] #列表尾部增加元素
c[:0] = [11,22] #头部增加元素
c[3:3] = [ 333] #第3个位置增加一个元素
c[:3] = [1,2,3,4] # 替换前三个元素,等号两边相等
c[3:] = [4,5,6] # 替换第三个之后的元素,等号两边不相等
c[::2] = ["a", "b","c"]  # 隔一个替换一个,注意个数,会报错,['a', 2, 'b', 4, 'c', 6]
c[::2] = [0]*3 #[0, 0, 0],也是隔一个换一个,[0, 2, 0, 4, 0, 6]

c[:3] = [] #删除前三个元素
del c[:3]  #删除前三个元素
del c[::2] #隔一个删除一个

 

posted @ 2021-08-18 20:50  zwx901323  阅读(46)  评论(0)    收藏  举报