Python进阶

张一默的菜园子 / 2024-01-11 / 原文

Python一切皆对象

对象介绍

  Python的对象是一种数据抽象或者数据结构抽象,对象应该同时具备:本征值(Indentity)、型式(Type)、值(Value)三个参数。

a = 45
print(id(a)) # 表示在python中的唯一内存地址,具备唯一性
print(type(a))
print(a)

/*-----output-------*/
2063144480432
<class 'int'>
45

  对象具体指变量Variable、类Class、函数Function,具备四种用途:

  • 作为返回值
  • 赋值给另一个对象
  • 作为函数参数传递
  • 添加到另一个集合对象

Object、Class、Type关系

  type可以用于查看对象,创建对象

a = 45
print(type(a))
print(type(type(a)))
print(type.__bases__)
print(type(type))

/*-----output-------*/
<class 'int'>  # a由int创建
<class 'type'> # int由type创建
(<class 'object'>,)  # type继承object
<class 'type'> # type自己创建自己

  class声明一个类

class STU:
    pass

stu = STU()
print(type(stu))
print(type(STU))

/*-----output-------*/
<class '__main__.STU'> # stu的实例化由STU完成
<class 'type'> # STU类由type创建

   object是所有class的基类

class STU:
    pass

print(STU.__bases__)

/*-----output-------*/
(<class 'object'>,)  # STU继承自object类

 1、所有的class都继承自object,所有的class都由type创建

  2、type本身也是class,因此type自身创建了自身

  3、python中一切皆对象,因为所有对象都由type创建,包括type类本身

Python的内置类型

  None:本身也是一个对象,全局只有一个

  数值:int,float,complex(复数),bool

  迭代类型:迭代器和生成器

  序列类型:list、bytes、bytearray、memoryview(二进制)、tuple、str、array

  映射:dict

  集合:set、frozenset(不可变)

  上下文管理:with(文件管理)

  其他:模块类型(import)、class、函数类型、方法类型、代码类型、type类型、object类型、ellipsis类型、notimplemented类型

  所有的对象都有类型

类变量与实例变量

  类变量是所有相关类实例共用的变量,只能通过类去修改类变量。通过类实例修改类变量时将会新建一个实例变量,无法修改类变量。

class A:
    # 类变量
    character = 0

    def __init__(self,x):
        self.x = x  # 实例变量


a = A(2)

# 可以通过类实例访问类变量忽然实例变量
print(a.x,a.character)

# 可以通过类访问类变量,但不能访问实例变量
print(A.character)

# 实例对象修改类变量时会重新创建一个对应的实例变量!
a.character = 5
print(a.character)
A.character = 3
print(a.character)  # a.character = 5

私有变量

  私有属性是类的一种私密变量,通过变量前加双下划线__私有属性不能被继承,私有属性不可以作为返回值。

class Date:
    def __init__(self, year, month, day):
        # 实例属性
        self.year = year
        self.month = month
        self.day = day

class User:
    def __init__(self,birthday):

        # 私有属性:具体日期是涉密的
        self.__birthday = birthday  # 私有属性只能在类方法中直接使用,无法通过结成,无法作为返回值

    def age_get(self):
        year = self.__birthday.year  # 只能间接返回,不建议将私有属性开放给外部访问
        return 2024 - year 

if __name__ == '__main__':
    user = User(Date(1990,4,24))
    print(user.age_get())

类方法

  类方法:传入cls,装饰器为classmethod。

  静态方法:传入self类实例,装饰器为staticmethod。硬编码。

  实例方法:传入self类实例。

class Date:
    def __init__(self, year, month, day):
        # 实例属性
        self.year = year
        self.month = month
        self.day = day

    # 实例方法:带有self参数,self是当前类的实例对象
    def __str__(self):
        return F"{self.year}/{self.month}/{self.day}"

    # 静态方法:不需要添加self实例对象,实例都可以调用
    @staticmethod
    def DataTransfer(DataStr):
        y,m,d = tuple(DataStr.split('-'))
        return Date(y,m,d) # 硬编码,如果类名更改,方法就会出错

    # 类方法:添加cls,指向类
    @classmethod
    def DataTransferCls(cls,DataStr):
        y,m,d = tuple(DataStr.split('-'))
        return cls(y,m,d)


if __name__ == "__main__":
    newday = Date(2024,1,8)
    print(newday)
    newday1 = Date.DataTransfer("2024-01-25")
    print(newday1)
    newday2 = Date.DataTransferCls("2024-08-03")
    print(newday2)

魔术方法

  魔术方法是类中固有功能的拓展。以__双下划线开头。

from abc import abstractmethod, ABCMeta

class Student:
    def __init__(self, StuList):
        self.StudentList = StuList

    # 魔法函数:枚举
    def __getitem__(self, item):
        return self.StudentList[item]

    # 魔法函数:成员长度
    def __len__(self):
        return len(self.StudentList)


stu = Student(['jim', 'tom', 'eason'])
# 常规遍历
for item in stu.StudentList:
    print(item)

# 魔术方法遍历
for item in stu:
    print(item)

# 魔法方法求指定成员长度
print(len(stu))

__len__方法

  len()方法会调用__len__,当统计的是Python的内部方法时,会直接调用C语言库,速度很快。

方法重写

  子类重写父类的方法

class Animal:
    def say(self):
        print("i'm animal")


class Dog(Animal):
    def say(self):  # 重写
        print("i'm a dog")


class Duck(Animal):
    def say(self):  # 重写
        print("i'm a duck")

鸭子类型

  多个类的方法名一致,将其存入列表进行迭代调用就可以实现类似多态的功能。这些类可以统称为鸭子类型。

class Dog():
    def say(self):  
        print("i'm a dog")


class Duck():
    def say(self):  
        print("i'm a duck")

dog = Dog()
duck = Duck()
animal = [dog,duck]
for an in animal:
    an.say()

抽象基类

  抽象基类的设计非常考验框架开发的功力,常规开发中仅使用多继承。

from abc import ABCMeta,abstractmethod

class AbstractClass(metaclass=ABCMeta):
    @abstractmethod
    def kind(self):
        pass
    @abstractmethod
    def name(self):
        pass

class HistoryBook(AbstractClass):
    def __init__(self):
        pass

    def kind(self):
        pass
    def name(self):
        pass


hb = HistoryBook()

类型判断isinstance

  类型读取是type(),类型判断使用isinstance()

    pass

class B(A):
    pass
a = A()
b = B()

print(isinstance(a,B))  # 父类实例是不是和子类一致  false
print(isinstance(b,A))  # 子类实例是不是和父类一致  true
print(type(a) is B) # 父类实例是不是和子类一致  flase
print(type(b) is A) # 子类实例是不是和父类一致  true

a = 12
print(isinstance(a,int))  # 判断常量是否为int true
print(type(a) is int)  

Python的自省机制

  编程语言中的自省机制是指知道一个变量叫什么?有什么用途。例如__dict_、dir()、_isinstance()、type()等。高级的自省则是反射hasattr()、getattr()、setattr()、delattr()。可以使用字符串去指向整个对象,达到怎么用?。

class Person:
    name = 'user'

class Student(Person):
    def __init__(self,fullname):
        self.fullname = fullname

user = Student("lucy")
# 通过__dict__查询属性:实例中所有的变量与值组成的字典
print(user.__dict__)
# dir会列出对象的所有可用属性
print(dir(user))