【python】面对对象入门篇

举报
子都爱学习 发表于 2021/10/30 07:33:42 2021/10/30
【摘要】 # 属性# 对对象状态的抽象,用数据结构来描述# 操作# 对对象行为的抽象,用操作名和实现该操作的方法来描述# 面对对象编程:# 1 一切皆对象# 2 对象是数据和操作的封装# 3 对象是独立的 但是对象之间可以相互作用# 4 目前oop是最接近人类认知的编程方式# 封装# 组装:将数据和操作组装到一起# 隐藏数据:对外只暴露一些接口,通过接口访问对象# 继承# 多复用,继承来的就不用自己来...

一.引言

类把数据与功能绑定在一起。创建新类就是创建新的对象 类型,从而创建该类型的新 实例 。类实例具有多种保持自身状态的属性。类实例还支持(由类定义的)修改自身状态的方法。

和其他编程语言相比,Python 只用了很少的新语法和语义就加入了类。Python 的类是 C++ 和 Modula-3 中类机制的结合体,而且支持所有面向对象编程(OOP)的标准特性:

类继承机制支持多个基类,

派生类可以覆盖基类的任何方法,

类的方法可以调用基类中相同名称的方法。

对象可以包含任意数量和类型的数据。和模块一样,

类也拥有 Python 天然的动态特性:在运行时创建,创建后也可以修改。

二.python面对对象术语

python面向对象的重要术语:
多态(polymorphism):一个函数有多种表现形式,调用一个方法有多种形式,但是表现出的方法是不一样的。
继承(inheritance)子项继承父项的某些功能,在程序中表现某种联系
封装(encapsulation)把需要重用的函数或者功能封装,方便其他程序直接调用
:对具有相同数据或者方法的一组对象的集合
对象:对象是一个类的具体事例
实例化:是一个对象事例话的实现
标识:每个对象的事例都需要一个可以唯一标识这个事例的标记
实例属性:一个对象就是一组属性的集合
实例方法:所有存取或者更新对象某个实例一条或者多条属性函数的集合。
类属性:属于一个类中所有对象的属性,
类方法:那些无须特定的对性实例就能够工作的从属于类的函数。

python内置类的属性

  • __dict__ : 类的属性(包含一个字典,由类的数据属性组成)
  • __doc__ :类的文档字符串
  • __name__: 类名
  • __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
  • __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

class Animal:     # 定义一个空类
    pass

Animal.__dict__
Animal.__doc__
Animal.__name__
Animal.__module__
Animal.__bases__
# {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Animal' objects>, '__weakref__': <attribute '__weakref__' of 'Animal' objects>, '__doc__': None}
# None
# Animal
# __main__
# (<class 'object'>,)

三.初识类

类是一种面对对象编程:1 一切皆对象 ,    2 对象是数据和操作的封装,    3 对象是独立的 但是对象之间可以相互作用,    4 目前oop是最接近人类认知的编程方式类对象: 类也是对象,类的定义执行后会生成一个类对象
类属性:对对象状态的抽象,用数据结构来描述,类定义中的变量和类定义的方法都是类的属性
类变量:属性也是标识符,也是变量
类方法:对对象行为的抽象,用操作名和实现该操作的方法来描述

# 类定义:
class Person:
    pass

print(Person.__doc__,Person.__name__)
# None Person
t1 = Person()
# t1是类Person实例化得到的实例,自动调用__init__初始化,第一个参数是self
print(type(t1), t1)
# <class '__main__.Person'> <__main__.Person object at 0x1012f6e80>
print(isinstance(t1, Person))
# True

 我们定义一个有属性和方法的类

class Person:
    def __init__(self, name, age=18):                    
        self.name = name
        self.age = age

    def showme(self):                                                               # 将类方法绑定在当前实例上,自动将绑定的实例注入给第一形参self
        print('{} is {} years old'.format(self.name, self.age))    

# showme是方法method,本质上就是普通的函数对象function,它一般要求至少有一个参数。第一个形式参数可以叫self(约定俗成)


tom = Person('Tom')
print(Person.showme)
print(tom.showme)
# 描述器<function Person.showme at 0x102fd9ca0>
# <bound method Person.showme of <__main__.Person object at 0x102fe5a90>>

self指代当前实例本身,当我们初始化实例调用类方法时,将类方法绑定在当前实例上,自动将绑定的实例注入给第一形参self
不过,要注意,实例变量是每个实例自己的变量,是自己独有的,类变量是类的变量,是类的所有实例共享的属性和方法

class Person:
    age = 3
    height = 170
    def __init__(self, name, age=18):
        self.name = name
        self.age = age

tom = Person('Tom')
jerry = Person('Jerry', 20)
Person.age = 30

print(type(Person),Person.__class__,)
print(Person.age,tom.age,jerry.age)

# <class 'type'> <class 'type'>
# 30 18 20

类的函数几种定义方法,注意类中禁止定义普通函数,调用时会报TypeError

class A:
    def showme():
        print("我是一个普通函数")

    def showme2(self):
        print("我是一个一般方法 me={}".format(self), type(self), self.__dict__)

    @classmethod
    def showme3(self):
        print("我是一个类方法 me={}".format(self), type(self), self.__name__)

    @classmethod
    def showme4(cls):
        print("我是一个类方法 me={}".format(cls), type(cls), cls.__name__)

    @classmethod
    def showme5():
        print("我是一个静态方法")

    @staticmethod
    def showme6():
        print("我是一个静态方法")

A.showme()
# 我是一个普通函数

a=A()

# 一般方法调用的两种方式
a.showme2()
A.showme2(a)
# 我是一个一般方法 me=<__main__.A object at 0x000001222F117E20> <class '__main__.A'> {}
# 我是一个一般方法 me=<__main__.A object at 0x000001222F117E20> <class '__main__.A'> {}

# 类方法调用
A.showme3()
a.showme3()
# 我是一个类方法 me=<class '__main__.A'> <class 'type'> A
# 我是一个类方法 me=<class '__main__.A'> <class 'type'> A

A.showme4()
a.showme4()
# 我是一个类方法 me=<class '__main__.A'> <class 'type'> A
# 我是一个类方法 me=<class '__main__.A'> <class 'type'> A

# A.showme5()
# a.showme5()
# TypeError: showme() takes 0 positional arguments but 1 was given

A.showme6()
a.showme6()
# 我是一个静态方法
# 我是一个静态方法

总结
类变量用全大写命名,类用驼峰命名法命名
类变量属于共享变量,所有实例都可以访问
对象可以动态的给自己加一个属性(动态语言的特性)
实例.__dict__[变量名] 和 实例.变量名  都可以访问实例属性(前者不会访问类字典)
实例变量会隐藏同名的类变量,实例无法直接访问
实例属性的查找顺序:先找自己的 __dict__ ,如果没有,通过属性 __class__找自己的类,再去类的 __dict__ 查找

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。