Python面向对象

一切皆对象,将现实世界事务使用类与实例来模拟(e.g. 灯、汽车、导弹、杯子)

一、三大特性

1.封装:

数据:(e.g. 名字、年纪);数据相关操作:(e.g. 获取名字、设置名字、获取年纪、设置年纪)

class Students:
    def __init__(self, name, age):
        print("初始化函数")
        self.name = name
        self.age = age

    def get_self(self):
        return self

    def describe_self(self):
        return self.age


s0 = Students("x", 417)
print(id(s0), isinstance(s0, Students))
print(s0.name, s0.age)
s1 = s0.get_self()
print(s1 == s0.get_self(), s1 is s0.get_self())
print(id(s1), id(s0.get_self()))
print(s1)
s2 = s0.get_self()
print(s1 == s2, s1 is s2)

 

2.继承:

子类拥有父类的数据以及操作,子类不需要从新编写。

子类(派生类),父类(基类)。

__base__:获取父类; __bases__:获取父类元组; __class__:返回实例对应的类。

# 子类拥有父类的数据以及操作
# 子类  派生类
# 父类  基类
"""
object是所有类的父类
Python3中可以省略父类object

object 是基类,父类
Person 是object的子类   是SuperPerson的父类
SuperPerson 是Person的子类

子类拥有父类的功能方法,先在子类中找对应的方法 子类如果没有 则去父类中找  父类也没有则去父类的父类 直到object
"""
import math
class Point(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return f"{self.x} {self.y}"


p0 = Point(0, 0)
print(p0)


class Circle(Point):
    def __init__(self, x, y, r):
        super().__init__(x, y)
        self.r = r

    def __str__(self):
        return f"{super().__str__()} r:{self.r}"

    def acreage(self):
        return math.pi * self.r ** 2


c0 = Circle(0, 0, 6)
print(c0)
print(c0.acreage())


class Rectangle(Point):
    def __init__(self, x, y, w, h):
        super().__init__(x, y)
        self.w = w
        self.h = h

    def __str__(self):
        return f"{super().__str__()} w:{self.w} h:{self.h}"

    def acreage1(self):
        return self.w * self.h


r0 = Rectangle(0, 0, 2, 3)
print(r0)
print(r0.acreage1())

 

        多继承:继承多个父类,java,c# 只支持单继承,通过接口等来实现多继承的功能,Python直接就可以有多个父类。

# 继承多个父类
# java,c# 只支持单继承,通过接口实现多继承功能
# paython直接就可以多个父类
class MoveAble:
    def __init__(self, speed):
        self.speed = speed

    def move(self):
        print(f"{self.speed}")

    def __str__(self):
        return f"攻速"


class SpeakAble:
    def __init__(self, language):
        self.language = language

    def speak(self):
        print(f"{self.language}")

    def __str__(self):
        return f"语种"


class AttackAble:
    def __init__(self, skill):
        self.skill = skill

    def attack(self):
        print(f"使用{self.skill}进攻")

    def __str__(self):
        return f"攻击"


class Person(MoveAble, SpeakAble):
    def __init__(self, name, speed, language):
        # 通过类名表明需要初始化哪个父类 必须传入self
        MoveAble.__init__(self, speed)
        SpeakAble.__init__(self, language)
        self.name = name

    def show(self):
        print(f"{self.name} 听召 前来")

    def __str__(self):
        return f"角色"


p0 = Person("x", 230, "chinese")
p0.move()
p0.speak()
p0.show()


class YS(Person, AttackAble):
    def __init__(self, name, speed, language, skill):
        Person.__init__(self, name, speed, language)
        AttackAble.__init__(self, skill)

    def __str__(self):
        return f"游戏"


ys0 = YS("x", 230, "chinese", "平A")
ys0.show()
ys0.move()
ys0.speak()
ys0.attack()

print(ys0)

# 多继承 mro: method(方法) retrieval(检索) order(顺序)
# python3 使用广度优先
print(YS.mro())

3.多态:

Python中没有多态,也可以理解到处都是多态。

两种形式:
(1).函数同名不同参数,通过*args实现。
(2).父子类多态,函数名参数都相同,但是实现不同,拥有多种实现

# 同名不同参数


def my_fun1(a):
    print(a)


my_fun1(6)


# 解释器 使用第二个函数 覆盖第一个 (第一个函数丢失)
def my_fun2(a, b):
    print(a, b)


my_fun2(10, 20)


# 通过形参*ages实现多态功能
def my_fun(*ages):
    print(ages)


my_fun(1)
my_fun(1, 2, 3)


class Animal:
    def walk(self, speed):
        print(f"z", speed)


class Dog(Animal):
    def walk(self, speed):
        print("ywb", speed)


class Cat(Animal):
    def walk(self, speed):
        print("zlzq", speed)

 

二、类与实例

类:是对现实世界描述的一种类型;”class 类名: pass“,类名是大驼峰;是抽象的,约定了未来实例应该有的内容,是实例的模板。

实例:调用类则生成实例,类名() 产生实例;实例是具体的,有具体数据,实例的内容依赖于类。

1.类中内容、self

self:出现在类内来代表未来的实例,需要通过实例来访问。

初始化函数:__init__(self);通过初始化self来初始化未来的实例;向self中添加数据 就是向实例中添加数据。

(1).实例属性
向实例中添加的数据;类内:通过self;类外:通过实例;需要通过实例来访问。
class MyClass3:
    def __init__(self, name):
        self.name = name


m1 = MyClass3(6)
print(m1.name)
(2).实例方法

第一个形参是self;类内:通过self;类外:通过实例;需要通过实例来访问。

class MyClass4:
    def __init__(self, x):
        self.x = x

    def instance_method(self, y):
        return self.x + y


m0 = MyClass4(6)
result = m0.instance_method(2)
print(result)
(3).类属性

向类中添加数据,获取与设置直接通过类名。
注意事项:通过实例可以获取类属性(不推荐);通过实例不可以设置类属性

class MyClass2:
    class_attribute = 10


print(MyClass1.class_attribute)
(4).类方法

第一个形参一般是cls;带有装饰器classmethod,将第一个形参编程类名。

目的:为了获取类相关信息(类名、父类、类注释)

实例可以获取类方法(不推荐)

class MyClass1:
    class_attribute = 10

    @classmethod
    def class_method(cls, multiplier):
        return cls.class_attribute * multiplier


result = MyClass1.class_method(6)
print(result)
(5).静态方法

        没有特殊形参,有装饰器staticmethod将方法升级为静态方法,通过类名调用,实例可以访问(不推荐),项目的辅助类一般都会使用静态方法。

class MyClass:
    @staticmethod
    def static_method(x, y):
        return x + y


result = MyClass.static_method(2, 6)
print(result)

2.抽象类

        一个特殊的类:内部可以编写抽象方法,抽象类不能直接实例化,也可以编写普通实例方法。子类继承抽象类,必须实现抽象类的抽象方法。

"""
抽象类:不直接实例化 通过子类来产生实例
"""
from abc import ABC, abstractmethod


class Animal(ABC):
    """
    抽象类:拥有抽象方法 不能直接实例化
    通过装饰器 abstractmethod把walk变为抽象方法
    """

    @abstractmethod
    def walk(self):
        pass

    def eat(self):
        print("c")


# a0 = Animal()
# print(a0, isinstance(a0, Animal))


class Dog(Animal):
    """
    抽象类子类: 必须实现抽象类中的抽象方法
    """
    def walk(self):
        print("ywb")


dog = Dog()
dog.eat()
dog.walk()
print(isinstance(dog, Dog), isinstance(dog, Animal))


class Cat(Animal):
    def walk(self):
        print("sxt")


cat = Cat()
cat.eat()
print(isinstance(cat, Cat), isinstance(cat, Animal))

 

3.单例类

只有一个实例

        通过控制构造函数判定是否需要从新生成实例:第一次,生成,放入类属性;以后,返回第一次生成的实例。

class Manage(object):
    instance = None

    def __new__(cls, *args, **kwargs):
        """
        对构造函数进行控制 不是每次都生成新的实例
        1、对类属性instance判断 如果不为空 则直接把他返回
        2、对类属性instance判断 如果为空 就构造一个实例 并且把实例赋予instance
        :param args:
        :param kwargs:
        """
        if not Manage.instance:
            Manage.instance = super().__new__(cls)
        return Manage.instance

    def __init__(self):
        """
        初始化函数 初始化实例 向self中添加内容
        """
        print("初始化函数执行")


m1 = Manage()
m2 = Manage()
print(m1 is m2, m1 is None, m2 is None)


class Manage:
    def __new__(cls, *args, **kwargs):
        if not hasattr(Manage, "instance"):
            obj = super().__new__(cls)
            setattr(Manage, "instance", obj)
        return getattr(Manage, "instance")


m3 = Manage()
m4 = Manage()
print(m3 is m4)

 

三、构造函数与析构函数

1.构造函数:

用于创建实例( self ),返回实例,通过父类来创建实例【super().__new__()】。

2.析构函数:实例不在使用,销毁之前执行。
"""
构造函数:创建并且返回实例(self)
初始化函数:self已经创建完成,可以向self中添加数据

析构函数:销毁实例 清理实例内存 实例不再使用则回收实例内存之前会执行对应的析构函数

"""


class MyClass:
    def __new__(cls, *args, **kwargs):
        # 调用父类的new方法创建一个实例
        instance = super().__new__(cls)
        print(f"构造函数", id(instance))
        # 将创建好的实例返回 返回给初始化函数
        return instance

    def __init__(self, name):
        print(f"初始化函数", id(self))
        self.name = name


mc0 = MyClass("xk")
print(id(mc0), mc0 is None)


class MyOpen:
    def __init__(self, filename, mode="r", encoding="utf8"):
        self.f = open(filename, mode=mode, encoding=encoding)

    def read_all(self):
        return self.f.read()

    def __del__(self):
        self.f.close()


m0 = MyOpen("./53.魔法函数.py")
print(m0.read_all())

 

四、属性封装与操作

口头称呼:类封装数据与操作,属性与行为;类属性,实例属性,公有属性,私有属性,保护属性。

property:fget,获取触发,@property;fset:设置触发,@属性名.setter;装饰器。

1. 属性封装:

class Person:
    def __init__(self, name, age, sex, height):
        self.__name = name
        self.age = age
        self.__sex = sex
        self.__height = height

    # 将指数变为函数
    @property
    def height(self):
        return self.__height

    # 指明属性的setter
    @height.setter
    def height(self, height):
        self.__height = height

    def get_name(self):
        return self.__name

    def set_name(self, name):
        if 1 <= len(name) <= 4:
            self.__name = name
        else:
            print("bhf")

    def __get_sex(self):
        print("发现你在获取")
        """当获取属性时 会触发"""
        return self.__sex

    def __set_sex(self, sex):
        print("发现你在获取")
        """当获取属性时 会触发"""
        if sex in ["男", "女"]:
            self.__sex = sex
        else:
            print("输入不合法")

    sex = property(__get_sex, __set_sex)


# 封装真正属性 拥有get与set方法
p0 = Person("x", 2000, "n", 190)

# 获取设置age 直接使用 (容易产生不合法数据)
print(p0.age)
p0.age = -6
print(p0.age)

# 获取设置name 需要通过函数 可以保证数据安全
print(p0.get_name())
p0.set_name("k")
print(p0.get_name())

print(p0.sex)
p0.sex = "nan"
print(p0.sex)

print(p0.height)
p0.height = 185
print(p0.height)

 

 2.属性操作:

"""
todo  属性 attribute
delattr: delattr(对象,"属性名") 返回布尔值
getattr: getattr(对象,"属性名") 返回属性值
hasattr: hasattr(对象,"属性名") 返回布尔值
setattr: setattr(对象,"属性名",属性值)
"""


import types


class Person:
    pass


p = Person()
p.name = "x"
Person.MAX_AGE = 2000

print(hasattr(p, "name"), hasattr(p, "MAX_AGE"))
print(hasattr(Person, "MAX_AGE"))

p.get_name = types.MethodType(lambda self: self.name, p)


@classmethod
def info(cls):
    return cls.__name__


Person.info = info


@staticmethod
def my_max(a, b):
    return a if a > b else b


Person.my_max = my_max

print(hasattr(p, "get_name"), hasattr(p, "info"), hasattr(Person, "info"), hasattr(Person, "my_max"))


if hasattr(p, "get_name"):
    value = getattr(p, "get_name")
    print(f"属性值为:{value()}")


if hasattr(p, "age"):
    pass
else:
    print("未发现属性age")
    setattr(p, "age", 2000)
    if hasattr(p, "age"):
        print("设置成功后的age值为", getattr(p, "age"))
        delattr(p, "age")
        if not hasattr(p, "age"):
            print("删除成功")

 

五、Python是一门解释性语言

可以向类中动态添加内容。

添加实例属性:实例名.属性名=值;

添加实例方法:实例名.实例方法=types.MethodType(原始方法名, 实例),原始方法第一个参数是self;

添加类属性:向类中添加类属性 类可以正常访问 所有实例均可访问。

添加类方法:向类中添加类方法  方法格式符合类方法格式  类与所有实例均可访问。

添加静态方法:向类中添加静态方法  方法要符合静态方法格式  类与实例均可访问。

import types


class Person:
    pass


p0 = Person()
p = Person()
# 向实例中添加实例数据  其他实例无影响
p.name = "张飞"
print(p.name)


def my_set_name(self, name):
    self.name = name


# 向实例中添加实例数据 其他实例无影响
p.set_name = types.MethodType(my_set_name, p)

p.set_name("赵云")
print(p.name)

# 向类中添加类属性 类可以正常访问 所有实例均可访问
Person.MAX_AGE = 120
print(Person.MAX_AGE, p.MAX_AGE, p0.MAX_AGE)


@classmethod
def my_info(cls):
    print(cls.__bases__)


# 向类中添加类方法  方法格式符合类方法格式  类与所有实例均可访问
Person.info = my_info

Person.info()
p0.info()
p.info()


#
@staticmethod
def my_max(x, y):
    return x if x > y else y


#  向类中添加静态方法  方法要符合静态方法格式  类与实例均可访问
Person.max = my_max

print(Person.max(10, 20), p.max(50, 100), p0.max(200, 500))

 

六、数据的访问级别

1.公有类型:public,普通名字,类内和类外,子类都可以使用。

2.私有类型:private,以 _ _开头,只能在类内访问。

3.保护类型:protect,以 _ 开头,在类内可以访问,在子类可以访问,在类外、可以 强制访问。

"""
公有类型:public 普通名字 类内与类外、子类都可以使用
私有类型:private 以__开头 只能在类内访问
保护类型:protect 以_开头 在类内可以访问 在子类可以访问 在类外可以强制访问

"""


class MyClass:
    def __init__(self, name, __age, _sex):
        self.name = name
        self.__age = __age
        self._sex = _sex

    def get_age(self):
        return self.__age

    def set_age(self, __age):
        self.__age = __age

    def get_sex(self):
        return self._sex

    def set_sex(self, _sex):
        self._sex = _sex

    def get_name(self):
        return self.name

    def set_name(self, name):
        self.name = name

    def __str__(self):
        return f"name:{self.name} age:{self.__age} sex:{self._sex}"


m0 = MyClass("x", 2000, "n")
print(m0)
m0.set_name("kk")
print(m0.get_name())
m0.set_age(10000)
print(m0.get_age())
m0.set_sex("n")
print(m0.get_sex())
m0.set_name("sz")
print(m0.get_name())
m0.set_sex("nv")
print(m0.get_sex())
m0.set_age(1000)
print(m0.get_age())

        Python 中的面向对象编程为程序员提供了一种结构化的方法来组织和管理代码,通过类和对象可以更好地模拟现实世界的复杂性,并提供了更灵活和可扩展的代码结构。 

  • 15
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python面向对象编程是一种编程范式,它将程序组织成对象的集合,每个对象都有自己的属性和方法。在Python中,可以通过定义类来创建对象,并通过实例化类来创建具体的对象。引用[1]中的代码示例展示了一个Animal类,其中包含了初始化方法和一个__str__方法来返回对象的描述信息。通过这个类,可以创建Animal对象,并通过print函数输出对象。引用中的代码示例展示了如何使用@property装饰器来定义类的属性和属性的访问方法。通过这种方式,可以在访问属性时像访问普通属性一样使用点号,而不需要使用方法调用的方式。引用中的代码示例展示了多态在Python中的应用。多态是面向对象编程的重要概念,它允许不同的对象以相同的方式对外部访问,但具体的实现可能不同。在这个示例中,father、son和daughter类都继承了father类,并重写了tell方法。通过调用不同的对象的tell方法,可以看到不同的输出结果。总之,Python面向对象编程是一种灵活且强大的编程方式,它允许开发者以对象为中心来思考和组织代码,提高了代码的可读性和可维护性。通过定义类、创建对象和使用类的属性和方法,可以实现丰富多样的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Python面向对象(全套)](https://blog.csdn.net/Thewei666/article/details/126652501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值