【python】面对对象入门篇
一.引言
类把数据与功能绑定在一起。创建新类就是创建新的对象 类型,从而创建该类型的新 实例 。类实例具有多种保持自身状态的属性。类实例还支持(由类定义的)修改自身状态的方法。
和其他编程语言相比,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__ 查找
- 点赞
- 收藏
- 关注作者
评论(0)