【python】面向对象(类型定义&魔法方法)

这篇具有很好参考价值的文章主要介绍了【python】面向对象(类型定义&魔法方法)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、引言

二、类型定义

1、什么是类型的定义?

2、案例

三、魔法方法

1、什么是魔法方法

2、基础部分

3、比较操作

4、容器类型

5、属性管理

6、封装

7、方法拓展

8、继承

9、多态


一、引言

        Python是一种面向对象的语言,它支持类(class)和对象(object)的概念。面向对象编程是一种程序设计模型,它将程序看作是由对象组成的,这些对象之间通过消息传递来相互通信和协作。

        Python中,类是创建对象的蓝图或模板,它定义了对象的基本结构和行为。对象是类的实例,可以根据类的定义来创建多个实例。每个对象都拥有类中定义的所有属性和方法。

下面是一个简单的Python类和对象的示例:

class Person:  
    def __init__(self, name, age):  
        self.name = name  
        self.age = age  
      
    def say_hello(self):  
        print(f"Hello, my name is {self.name} and I'm {self.age} years old.")  
  
# 创建Person类的实例  
p1 = Person("zs", 25)  
p2 = Person("ls", 30)  
  
# 调用对象的say_hello方法  
p1.say_hello()  # 输出:Hello, my name is Alice and I'm 25 years old.  
p2.say_hello()  # 输出:Hello, my name is Bob and I'm 30 years old.

 

在例子中,我们定义了一个名为Person的类,它有两个属性nameage,以及一个方法say_hello。通过调用Person类的构造函数__init__,我们创建了两个Person对象p1p2,分别代表"zs"和"ls"两个人。然后我们可以通过调用对象的say_hello方法来输出问候语。

面向对象编程的核心概念包括封装、继承、多态和抽象。在Python中,这些概念都有相应的语法和机制来支持。通过使用面向对象编程,我们可以更好地组织和管理代码,使其更易于维护和扩展

二、类型定义

1、什么是类型的定义?

        在编程中,类型是用于描述变量或数据结构的特征和行为的抽象概念。类型定义了变量或数据结构可以存储的数据的类型以及可以执行的操作。通过使用类型,程序员可以确保变量和数据结构中存储的数据是有效的,并且可以在编译时检测到潜在的错误。

        在许多编程语言中,类型可以分为静态类型和动态类型。静态类型在编译时进行类型检查,而动态类型则在运行时进行类型检查。

        静态类型定义了变量或数据结构在编译时必须具有的类型。这种类型通常在声明变量或数据结构时指定,并且不允许在运行时更改。静态类型的优点是编译器可以在编译时捕获许多类型相关的错误,从而提高代码的可靠性和安全性。然而,静态类型也限制了程序员在运行时动态更改变量类型的灵活性。

        动态类型定义了变量或数据结构在运行时可以具有的类型。这种类型可以在运行时更改,并且不需要在声明时指定。动态类型的优点是提供了更大的灵活性,使得程序员可以在运行时根据需要更改变量的类型。然而,动态类型也带来了运行时类型错误的潜在风险,因为它们可能在运行时引发异常或错误。

        类型是编程中的重要概念,用于描述变量和数据结构的特征和行为。它们提供了编译时的类型检查和运行时的灵活性,帮助程序员编写更可靠和可维护的代码。

2、案例

定义一个 dog 类:

class Dog:
"""小狗类定义"""
pass

在 Python 中,首字母大写的名称指的是类。

这个类定义是可以不带 ( ) ,括号中指定的父类型。


给 Dog 类定义属性:

class Dog:
"""小狗类定义"""
name: str = '小黑'
age: int = 3

编写对象,获取对象的属性:

d = Dog()
print(f"name:{d.name},age:{d.age}")

Python 中对于对象的属性是属于动态可变化的。

d = Dog()
d.age = 30
d.gender = '公'
print(f"name:{d.name},age:{d.age},gender:{d.gender}")

也可以给类型添加方法,方法就是定义再类中的函数。

def sit(self):
pass

每个与类相关联的方法调用都自动传递实参self,它是一个指向实例本身的引用,让实例能够访问类中的属 性和方法。

def sit(self):
print(f'小狗{self.name}蹲下了')

携带多个参数时,其他的参数放在 self 之后:

def eat(self, food: str):
print(f'小狗{self.name}吃下了{food}')

三、魔法方法

1、什么是魔法方法

        Python中,魔法方法是指那些以双下划线开头和结尾的方法,例如__add__()。这些方法通常用于运算符重载,当对类的某个操作时后端自动调用,而不需要自己直接调用。

如:当使用+将两个数字相加时,在类内部会调用__add__()方法。

2、基础部分

init 被用于初始化实例对象,new方法创建对象后就会调用该方法对实例的属性进行初始化。

class T:
def __init__(self):
self.name = 'sa'
self.pwd = '123'
t = T()

del 是析构方法,当对象的引用计数变为0时,这个对象会被销毁掉,此时就会调用del方法

class T:
def __del__(self):
print("对象被销毁")
t = T()
# t指向0,此前创建的T的实例被销毁
t = 0

call 允许一个类的实例像函数一样被调用,这是一个非常重要的特性

class T:
def __call__(self, *args, **kwargs):
print("类的实例可以像函数一样被调用")
t = T()
t()

len 是内置函数,len(t) 会调用实例的 len 方法

class T:
def __len__(self):
return 100
t = T()
print(len(t))

当被 str() 调用时, 调用该 str 方法

class T:
def __str__(self):
return f"我是{T.__name__}的一个实例"
t = T()
print(t)

bool 可用于逻辑判断部分

class T:
def __init__(self, age):
self.age = age
def __bool__(self):
return self.age > 18
print(bool(T(17) and T(19)))

3、比较操作

        比较操作可以是算术比较(例如等于、不等于、大于、小于、大于等于、小于等于)或者字典比较(例如键在字典中、键不在字典中)。

  1. 算术比较:

    • 等于 (==):eq(self, other)定义等于号的行为。
    • 不等于 (!=):ne(self, other)定义不等号的行为。
    • 大于 (>):gt(self, other)定义大于号的行为。
    • 小于 (<):lt(self, other)定义小于号的行为。
    • 大于等于 (>=):ge(self, other)定义大于等于号的行为。
    • 小于等于 (<=):le(self, other)定义小于等于号的行为。
  2. 字典比较:

    • 键在字典中 (key in dict):如果给定的键在字典中,则返回True,否则返回False。
    • 键不在字典中 (key not in dict):如果给定的键不在字典中,则返回True,否则返回False。

这些比较操作可以用于各种数据类型,包括数字、字符串、列表、元组、集合和字典等。

案例:文章来源地址https://www.toymoban.com/news/detail-755066.html

class Student:
def __init__(self, age):
self.age = age
def __lt__(self, other):
return self.age < other.age
def __eq__(self, other):
return self.age == other.age
s1 = Student(3)
s2 = Student(3)
print(s1 < s2)
print(s1 == s2)
print(s1 is s2)

4、容器类型

getitem, setitem, delitem getitem

        定义获取容器中指定元素的行为,相当于 self[key], setitem 定义设置容器中指定元素的行 为,相当于 self[key] = value, delitem 定义删除容器中指定元素的行为,相当于 del self[key]。

        字典就是实现了这三个魔法方法,才提供了以[]为基础的操作。

class MyData:
def __init__(self, data=None):
if data is None:
data = set()
self.data = data
def __getitem__(self, item):
return self.data.get(item)
def __setitem__(self, key, value):
self.data[key] = value
def __delitem__(self, key):
del self.data[key]
my_data = MyData()
my_data['name'] = '小刚'
my_data['age'] = 14
print(my_data['name'])
print(my_data['age'])

如果一个对象实现了 iter , 那么它就是一个可迭代对象

如果既实现 iter 又实现 next ,那么它就是一个迭代器

class Color(object):
def __init__(self):
self.index = -1
self.colors = ['red', 'white', 'black', 'green']
def __iter__(self):
self.index = -1
return self
def __next__(self):
self.index += 1
if self.index >= self.colors.__len__():
raise StopIteration
return self.colors[self.index]
color_object = Color()
# 遍历输出所有颜色
for color in color_object:
print(color)

5、属性管理

class Plane(object):
category = '飞机'
p1, p2 = Plane(), Plane()
# print(p1.category, p1.category)
# Plane.category = '拖拉机'
# print(p1.category, p2.category)
# print(p1.category, p1.category)
# p1.category = '拖拉机'
# print(p1.category, p2.category)

这里主要涉及到了类属性与对象属性实例属性的区别

python中,实例属性存储在一个字典(dict)中,对于属性的操作,都是在操作这个字典

p1.name = 'sa'
print(p1.__dict__)

也可以直接操作这个字典

p1.name = 'sa'
p1.__dict__['pwd'] = '123'
print(p1.pwd)

python中对象的属性为什么可以动态变化?


类属性同样是存储在字典中,只是这个字典是类的字典

可以通过类名和对象名来调用,但是只能通过类名修改,类属性对于该类对象是共享的

类的属性和方法存在在类的 dict 之中

p1, p2 = Plane(), Plane()
print(Plane.__dict__)

属性寻找规则: 先找实例的 dict ,再去查找类的 dict


案例:

class Dog:
name: str = '小黑'
age: int = 3
d1 = Dog()
d1.name = "大黄"
d2 = Dog()
Dog.name = "小白"
print(d1.name)
print(d2.name)

6、封装

        python中,使用一个下划线就等于向使用者宣布这个属性是私有的,但你仍然可以直接对其修改,单个 下划线更像是一种约定,而非技术上的强硬限制。即便使用了双下划线,也仍然有办法直接对其修改, 但这已经不是类所要解决的问题了,一个人执意破坏数据,他总是能找到办法。

案例:

class Stu:
def __init__(self, name, age):
self.__name = name
self.__age = age
def get_name(self):
return self.__name
def set_name(self, name):
self.__name = name
def get_age(self):
return self.__age
def set_age(self, age):
self.__age = age
stu1 = Stu('小明', 14)
stu2 = Stu('小红', 14)
print(stu1.get_name(), stu1.get_age())
print(stu2.get_name(), stu2.get_age())

还可以通过其他方式来实现封装

class Book:
def __init__(self, price):
self._price = price
@property
def price(self):
return self._price
@price.setter
def price(self, price):
if price > 0:
self._price = price
else:
raise Exception('价格不能为负数')
book = Book(58.5)
print(book.price)
book.price = -1
print(book.price)

使用 @property 装饰器修饰 price 方法后,你就可以像使用属性一样使用 price ,如果你希望可以对 price 进行赋值,那么需要用 @price.setter 装饰器再装饰一个方法,该方法完成对 _price 属性的赋值操 作。 我们以为自己直接操作了对象的属性,但其实我们是在使用类的方法,而且关键的是省去了调用方法时 的那对小括号

7、方法拓展

类方法 : 可以通过类名调用的方法

加上注解,修改参数为 cls (当前类),可以通过 cls 调用类的属性

@classmethod
def run(cls):
print(cls.__name)

静态方法 : 可以通过类名与对象来调用,但是无法使用类变量

@staticmethod
def say():
print("hello world")

8、继承

如果没有指定基类,会默认继承 object 类, object 是所有类的基类,它提供了一些常见方法, 比如 __str__,我们用案例来演示

class Dog(object):
pass

类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类

class A:
pass
class B:
pass
class C(A):
pass
class D(A, B):
pass

查看继承关系

print(D.__bases__)
print(D.__mro__)

继承可以继承属性与方法

class Father:
money = 100
class Son(Father):
pass
s = Son()
print(s.money)
class Father:
money = 100
def hello(self):
print("hello world")
class Son(Father):
pass
s = Son()
s.hello()
class Father:
money = 100
def hello(self):
print("hello world")
class Mother:
money = 200
def cook(self):
print("煮饭")
class Son(Father, Mother):
pass
s = Son()
print(s.money)
s.hello()
s.cook()

当属性和方法重复时,越往前优先级越高

9、多态

        多态是指同一个事件发生在不同的对象上会产生不同的结果,或者一个对象可以有多种形态。它是一种机制、一种能力,在类的继承中得以实现,在类的方法调用中得以体现。多态的存在可以消除类型之间的耦合关系,通过分离做什么和怎么做,将接口和实现分离开来。

        多态可以分为引用多态和方法多态。引用多态是指同一个对象变量可以指向多种实际类型的现象,而方法多态是指同一个方法可以被不同的对象调用产生不同的效果。

        多态是面向对象编程中非常重要的概念,它可以帮助我们编写更加灵活、可扩展和维护性更高的代码。

案例:

class Animal(object):
def play(self):
pass
class Tiger(Animal):
def play(self):
print("正在表演老虎吃人")
class Lion(Animal):
def play(self):
print("正在表演狮子跳火圈")
class Person(object):
def show(self, a: Animal):
print("动物开始表演了")
a.play()
p = Person()
tiger = Tiger()
lion = Lion()
# 让老虎表演
p.show(tiger)
# 让狮子表演
p.show(lion)

到了这里,关于【python】面向对象(类型定义&魔法方法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Python 面向对象(一)(成员方法、类和对象)

    学校开学,要求学生填写自己的基础信息,一人发一张白纸,让学生自己填 改为登记表,打印出来让学生自行填写: 在程序中简单使用变量来记录学生信息  使用变量记录数据太乱了。 如果程序中也和生活中一样 可以设计表格 可以将设计的表格打印出来 可以将打印好的表

    2024年02月15日
    浏览(35)
  • 【python全栈开发】面向对象进阶

    实例变量:属于对象,每个对象中各自维护自己的数据。 类变量:属于类,可以被所有对象共享,一般用于给对象提供公共数据(类似于全局变量)。 类变量和实例变量的区别示例: 类变量和实例变量+继承问题: 通常来说,调用的变量不是对象变量时,就会去对应的类中

    2024年02月21日
    浏览(72)
  • Python 面向对象编程:类、对象、初始化和方法详解

    Python 是一种面向对象的编程语言。在 Python 中,几乎所有东西都是对象,都具有其属性和方法。 类似于对象构造函数或用于创建对象的“蓝图”的类。 要创建一个类,请使用 class: 示例,创建一个名为 MyClass 的类,其中包含一个名为 x 的属性: 现在,我们可以使用名

    2024年02月08日
    浏览(46)
  • Python教程(22)——Python面向对象的属性和方法

    在Python面向对象编程中,属性和方法是类及其对象的重要组成部分。如果说封装、继承和多态是面向对象编程中的思想,那么类的属性和方法就是骨架,因为有属性和方法,面向对象编程才变的有血有肉。 属性是类或对象所拥有的数据,它用于描述对象的特征和状态。属性可

    2024年02月03日
    浏览(27)
  • Python面向对象编程,实现模块化开发

    面向对象编程(Object Oriented Programming,OOP)是一种编程范式,它将真实世界中的事物抽象成程序中的对象,并通过对象之间的相互作用来完成程序的逻辑。 封装 (Encapsulation) 封装是指把数据和行为结合成一个相对独立的整体,防止程序中其他部分直接访问或修改这个整体,而

    2024年02月05日
    浏览(121)
  • Python基础-11 面向对象编程_各种方法

    python本身支持类的动态属性 直接使用等号=,给一个属性赋值 如果这个属性存在,则会修改该属性的值 如果这个属性不存在,则会给对象添加一个新的属性及对应的值 如果需要禁止动态添加类的属性,可以使用 __slots__ 属性,如下示例 这个属性直接定义在类中,是一个元组,用来规定

    2023年04月17日
    浏览(34)
  • 🔥🔥Java开发者的Python快速进修指南:面向对象基础

    当我深入学习了面向对象编程之后,我首先感受到的是代码编写的自由度大幅提升。不同于Java中严格的结构和约束,Python在面向对象的实现中展现出更加灵活和自由的特性。它使用了一些独特的,如self和cls,这些不仅增强了代码的可读性,还提供了对类和实例的明确

    2024年02月05日
    浏览(49)
  • 🔥🔥Java开发者的Python快速进修指南:面向对象进阶

    在上一期中,我们对Python中的对象声明进行了初步介绍。这一期,我们将深入探讨对象继承、组合以及多态这三个核心概念。不过,这里不打算赘述太多理论,因为我们都知道,Python与Java在这些方面的主要区别主要体现在语法上。例如,Python支持多重继承,这意味着一个类可

    2024年02月05日
    浏览(48)
  • python 面向对象的概念及使用方法~(基础小知识)

    编程语言中,一般有两种编程思维,面向过程和面向对象。 面向过程,看重的是解决问题的过程。 这好比我们解决日常生活问题差不多,分析解决问题的步骤,然后一步一步的解决。 而面向对象是一种抽象,抽象是指用分类的眼光去看世界的一种方法。 Python 就是一门面向

    2024年02月06日
    浏览(41)
  • 🔥🔥Java开发者的Python快速进修指南:面向对象--高级篇

    首先,让我来介绍一下今天的主题。今天我们将讨论封装、反射以及单例模式。除此之外,我们不再深入其他内容。关于封装功能,Python与Java大致相同,但写法略有不同,因为Python没有修饰符。而对于反射来说,我认为它比Java简单得多,不需要频繁地获取方法和属性,而是

    2024年02月05日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包