知识点 —— Python进阶-2

Posted 海绵小青年

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识点 —— Python进阶-2相关的知识,希望对你有一定的参考价值。

Python进阶–2

面向对象–基础

  • 引入理解

https://blog.csdn.net/shenzixincaiji/article/details/83576687

类、对象、属性、方法
  • 基础
class student:					# 类
    age = 18					# 类的属性
    tall = 175
    phone = 'huawei'

    def sleep(self):			# 类的方法
        print('正在睡觉')

# basic												# 对象lily和对象Tom继承student类,两者的数据id一致
lily = student()
print(lily.age, lily.tall, lily.phone)		
print('lily.age的id:', id(lily.age))			  
lily.sleep()								   

Tom = student()
print(Tom.age, Tom.tall, Tom.phone)
print('Tom.age的id:', id(Tom.age))
Tom.sleep()

print('----------------------------------------')
# change 类
student.age = 20									# 第一次改变类属性,两个对象的属性也一起改变
print(lily.age, Tom.age)							# 即对两个对象都有影响
print(id(lily.age), id(Tom.age))
print('----------------------------------------')

# change 对象lily
lily.age = 19										# 改变对象lily的属性(对象属性),创建了动态的对象属性与起绑定
print(lily.age, Tom.age)							# 改变的结果不影响另一个对象的属性
print(id(lily.age), id(Tom.age))
print('----------------------------------------')
# change 类		
student.age = 21								# 再次改变类属性,lily的属性已经不受影响,Tom的属性仍会受到影响
print(lily.age, Tom.age)
print(id(lily.age), id(Tom.age))

  • 高级一点
class student:
    tall = 'None'                           # 类属性,其变化同于基础部分的讲解
    def __init__(self):                     # 魔术方法
        self.name = 'None'                  # 对象属性,应用到具体对象都会给定一个初始值,可根据具体需要再做修改
        self.age = 'None'
        self.phone = 'None'

    def sleep(self):
        print('正在睡觉'.format(self.name))	# self就相当于具体的对象

# basic
lily = student()
print(lily.age, lily.name, lily.phone)
print('lily.age的id:', id(lily.age))
lily.sleep()									# self.name == lily.name

Tom = student()
print(Tom.age, Tom.name, Tom.phone)
print('Tom.age的id:', id(Tom.age))
Tom.sleep()										# self.name == Tom.name

print('----------------------------------')
# 初始化后的具体赋值
lily.name = 'lily'
lily.age = '15'
lily.phone = 'huawei'
print(lily.age, lily.name, lily.phone)
print('lily.age的id:', id(lily.age))
lily.sleep()

print('----------------------------------')
Tom.name = 'Tom'
Tom.age = '15'
Tom.phone = 'iphone'
print(Tom.age, Tom.name, Tom.phone)
print('Tom.age的id:', id(Tom.age))
Tom.sleep()

  • 总结

类属性

使用同一类创建不同的对象

  • 若没有改变过类属性,可以通过类属性改变,来改变对象中对应类属性的值。一起改变
  • 若某一对象更改了类属性的值,则建立动态对象绑定,此对象中类属性变为修改后的数值;其他对象的类属性不变
  • 再次改变类属性,已经动态绑定的对象,其对象的类属性不会受到影响;对于没有“私自”更改类属性的对象,其对应的类属性仍然会受到影响

对象属性

对象属性是依据类创建对象的时候,每个对象都具有的公共属性

其数值的更改需要通过调用对象属性赋值来修改,不能通过类属性更改

总结

类属性,不允许对象私自修改,有类统一修改,影响所有对象

对象属性,依据对象的特点,可以自己做出特定的修改。类没有权限去修改对象属性

对象方法
  • 理解
class student(object):
    tall = 'tom'                           # 类属性,其变化同于基础部分的讲解
    def __init__(self, nickname):                     # 魔术方法
        self.name = nickname                 # 对象属性,应用到具体对象都会给定一个初始值,可根据具体需要再做修改
        self.age = 'None'
        self.phone = 'None'

    def run(self):
        print("在跑步".format(self.name))	# 调用对象属性
        print("在跑步".format(self.tall))	# 调用类属性
        self.sleep()					 # 调用其他对象方法

    def sleep(self):
        print('在睡觉')


# basic
lily = student('dahuang')
lily.sleep()
lily.run()

在睡觉
dahuang在跑步
tom在跑步
在睡觉

对象方法

可以调用类属性,也可以调用对象属性

对象方法中的参数是对象self

对象方法之间可以相互调用

类方法
  • 理解
class student(object):
    tall = 'tom'                           # 类属性,其变化同于基础部分的讲解
    def __init__(self, nickname):                     # 魔术方法
        self.name = nickname                 # 对象属性,应用到具体对象都会给定一个初始值,可根据具体需要再做修改
        self.age = 'None'
        self.phone = 'None'

    def sleep(self):
        print('在睡觉')

    @classmethod
    def test(cls):
        print('只能调用类属性:',cls.tall)

# basic
student.test()

只能调用类属性: tom

类方法

依赖装饰器,且只能调用类属性,不能调用对象属性(会报错)

类方法中的参数是类,不依赖对象,可以独立于对象做一些处理

类方法中不能调用对象方法

  • 类方法和对象方法的理解

类属性是公共属性,对象属性是私有属性

类方法只能调用类属性;而对象方法既能调用对象属性,也能调用类属性

静态方法
class student(object):
    __tall = 'tom'                              # 对类属性进行私有化
    high = 12
    def __init__(self, nickname):
        self.name = nickname
        self.age = 'None'
        self.phone = 'None'

    def sleep(self):
        print('在睡觉')

    @staticmethod
    def casual():
        print('只能调用类属性tall:', student.__tall)
        print('只能调用类属性high:', student.high)


# basic
student.casual()

只能调用类属性tall: tom
只能调用类属性high: 12

也是只能访问公共类属性

静态方法和类方法区别

不同

  • 装饰器不同
  • 参数不同,一个有cls,一个无cls

相同

  • 都只能访问类属性和方法,对象属性和对象方法无法访问
  • 都可以通过类名调用访问
  • 都可以在对象创建之前调用,不依赖于对象
总结–↑
  • 几种方法都可以接受外部参数
class student(object):
    __tall = 'tom'                              # 对类属性进行私有化
    high = 12
    def __init__(self, nickname):
        self.name = nickname
        self.age = 'None'
        self.phone = 'None'

    def sleep(self, outer1):
        print('outer1:', outer1, self.__tall, self.high)

    @classmethod
    def casual(cls, outer2):
        print('outer2:', outer2, cls.__tall, cls.high)

    @staticmethod
    def casual(outer3):
        print('outer3:', outer3, student.__tall, student.high)

# basic
student('dahuang').sleep(1)
student.casual(2)
student.casual(3)

outer1: 1 tom 12
outer3: 2 tom 12
outer3: 3 tom 12

  • 各自特点

对象方法

  • 可以调用对象属性,也可以调用类属性(私有和非私有的)
  • 依赖对象,没有对象就不能调用对象方法
  • 没有装饰器
  • 必须有self对象参数,也可以有外部参数

类方法

  • 只能调用类属性(私有的和非私有的)
  • 不依赖对象,没有对象也可以调用类方法
  • 需要装饰器,classmethod
  • 必须有cls参数,也可以有其他外部参数

静态方法

  • 只能调用类属性(私有和非私有的)
  • 不依赖对象,没有对象也可以调用静态方法
  • 需要装饰器,staticmethod
  • 不需要任何参数,但是也可以添加外部参数

面向对象–魔术方法

魔术方法
  • http://c.biancheng.net/view/7817.html
  • https://www.cnblogs.com/zhangboblogs/p/7860929.html
  • https://www.cnblogs.com/nmb-musen/p/10861536.html
常用魔术方法
# __new__(self)  和  __init__(self)
# 先执行new,再执行init,不要随便动用new魔术方法

class Test:
    def __init__(self):
        print("init方法")

    def __new__(cls, *args, **kwargs):
        print("重写new方法")
        return super().__new__(cls)


m = Test()

重写new方法
init方法

# _del__(self) :析构器
# 当一个实例被销毁的时候调用的方法
# 非手动调用时会在程序最后触发,而手动调用del时则会触发__del__,并不是程序最后

class Test:
    def __init__(self, name):
        self.name = name

    def __del__(self):
        print("触发__del__")


t = Test("python")
print("end")

del t
print("end")
# __len__

class Test:
    def __init__(self, name):
        self.name = name

    def __len__(self):
        return len(self.name) # 必须有返回值,且必须为int类型


t = Test("mingming")
print(len(t))

8

# __str__

class Test:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return "hello world" #必须有返回值,且必须为str类型

# 调用方法1
t = Test("mingming")
print(t)

# 调用方法2
print(t.__str__())

hello world

hello world

# __bool__

class Test:
    def __init__(self, name):
        self.name = name

    def __bool__(self):
        if self.name =="python": # 返回对象必须是True 或 False
            return True
        else:
            return False

t = Test("python")
t1 = Test("java")
print(bool(t))
print(bool(t1))

True

False

面向对象–私有化

类属性的私有化
  • 目的

为了防止外部任意修改公共类属性

私有化的类属性只能够被类方法修改

class student(object):
    __tall = 'tom'                              # 对类属性进行私有化
    high = 12
    def __init__(self, nickname):
        self.name = nickname
        self.age = 'None'
        self.phone = 'None'

    def sleep(self):
        print('在睡觉')

    @classmethod
    def test(cls):
        print('只能调用类属性tall:',cls.__tall)
        print('只能调用类属性high:', cls.high)

    @classmethod
    def update(cls):
        cls.__tall = '把tom改为tttom'
# basic
student.test()
student.high = '修改后'
student.tall = '修改后'    # 私有属性,不可外界修改
student.test()

student.update()         # 使用类方法修改私有属性
student.test()

只能调用类属性tall: tom
只能调用类属性high: 12
只能调用类属性tall: tom
只能调用类属性high: 修改后
只能调用类属性tall: 把tom改为tttom
只能调用类属性high: 修改后

对象属性的私有化
  • 目的

为了防止对象属性被不合理的修改

可以通过对象方法来修改私有的对象属性

class PositiveInteger():
    def __init__(self):
        self.__name = 'Tom'
        self.__age = 15

    def setName(self, newname):
        self.__name = newname

    def setAge(self, newage):
        if 0 < newage < 100:
            self.__age = newage
        else:
            print('年龄不符合要求')

    def __str__(self):
        return '学生的年龄:,学生的名字:'.format(self.__age, self.__name)

i = PositiveInteger()

print(i)
# i.__name    这是无法修改的
i.setName('TTTTom')
i.setAge(150)
print(i)

学生的年龄:15,学生的名字:Tom
年龄不符合要求
学生的年龄:15,学生的名字:TTTTom

私有化的本质–↑
  • 本质是通过修改内部的名字,让你无法通过原名字访问
  • 可以找到真实的名字进行访问,但是不建议这样用
class PositiveInteger():
    __name1 = 'lily'

    def __init__(self):
        self.__name = 'Tom'
        self.__age = 15

    def setName(self, newname):
        self.__name = newname

    def setAge(self, newage):
        if 0 < newage < 100:
            self.__age = newage
        else:
            print('年龄不符合要求')

    def __str__(self):
        return '学生的年龄:,学生的名字:'.format(self.__age, self.__name)


i = PositiveInteger()

print(dir(PositiveInteger))
print(dir(i))		# 等价于 i.__dir__()

print(i)
i._PositiveInteger__age = 99	# 不过不建议这样修改
print(i)

学生的年龄:15,学生的名字:Tom
学生的年龄:99,学生的名字:Tom

@property
  • 目的

即想达到对象属性私有化的目的

又想通过 对象.属性 的方法来调用和修改私有化后的属性

class PositiveInteger():

    def __init__(self):
        self.name = 'Tom'
        self.__age = 15

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, newage):
        if 0 < newage < 100:
            self.__age = newage
        else:
            print('年龄不符合要求')

    def __str__(self):
        return '学生的年龄:,学生的名字:'.format(self.__age, self.name)


i = PositiveInteger()

print(i, i.age)
i.age = 99
print(i, i.age)

学生的年龄:15,学生的名字:Tom 15
学生的年龄:99,学生的名字:Tom 99

面向对象–关联关系

概念辨析
  • is a

是一种继承关系

A is a B B是A的基类(父类)

可以产生代码上的重用性

比如:兔子 is a 动物

就是说兔子继承了动物的一些特点:有腿、有耳朵

具体到代码层面就是说:它可以继承动物(父)类的一些属性,如果有需要增加的可以再写

兔子爱吃的素食有哪些,就是兔子类不能从动物类继承的属性,因为有些动物不吃素的

就可以在动物类的基础上,添加喜欢吃的食物这一属性

  • has a

是一种包含关系

A has a B A包含B

比如:汽车 has a 轮胎,但是不能说汽车 is a 轮胎

包含关系具体到代码层面就是调用

汽车有很多属性:轮胎类型、车座类型、价格…

轮胎也有很多属性:价格、材质、防滑等级…

汽车对象就可以调用轮胎对象里面的一些属性

宝马牌汽车的轮胎是米其林材质的,价格是…。防滑等级是…

实例理解

讲的是 has a的包含关系

is a的继承关系在后续有介绍

class Compter:
    def __init__(self,brand,type,color):
        self.brand=brand
        self.type=type
        self.color=color

    def online(self):
        print("正在使用电脑上网")

    def __str__(self):
        return self.brand + '-------'+self.type+'------'+self.color

class Book:
    def __init__(self,bname,number,author):
        self.bname=bname
        self.number=number
        self.author=author

    def __str__(self):
        return self.bname+self.author+self.number

class sudent:
    def __init__(self,name,compter,book):
        self.name=name
        self.compter=compter
        self.Book=[]
        self.Book.append(book)
    def __str__(self):
        return self.name+'------->'+str(self.compter)+'-----'+str(self.Book)

C=Compter知识点 —— Python进阶-2

知识点 —— Python进阶-2

知识点 —— Python进阶-2

Python爬虫从入门到进阶之爬虫简介

python小白进阶之路—基础知识练习

Python入门自学进阶-Web框架——20Django其他相关知识2