第十四天python3 面向对象
1、面向对象
是对现实世界中的事物进行抽象的方式;
一切皆对象;
对象是数据和操作的封装;
对象之间相互独立,但也可以相互作用;
三要素:
封装:
数据与方法的集合;
提供一个或者多个接口来访问;隐藏数据,使用者不需要知道具体是怎么运作的;
继承:多继承,少修改,继承来的就不用自己写了;
多态:动态绑定;
2、类
类是一系列事物的统称,同类事物必定具有相同的特征;对应到类中是变量和方法;
定义类的语法格式:
class Cat:
pass
3、对象
对象是类的具体表现形式;是实际存在的个体;
#定义类
class Cat:
print("Hello Word") #创建对象,也叫实例化对象
cat1=Cat()
4、成员变量
用于描述对象的固有状态或属性
class 类名:
def __init__(self):
self.变量名1 = 值1
self.变量名2 = 值2
5、成员方法
用于描述对象的固有行为;
class 类名:
def __init__(self):
self.变量名1 = "值1"
self.变量名2 = "值2" def 方法名1(self):
方法体
def 方法名2(self):
方法体 调用方法格式:
对象名.方法名()
#######################################
class MyClass:
"""A example class"""
x = 'abc'
def foo(self):
return 'My Class' #MyClass这个类调用共有属性
print(MyClass.x)
abc #返回内存中函数对象的地址
print(MyClass.foo)
<function MyClass.foo at 0x0000020F73459F70> #没有被实例化而调用foo方法,提示foo()需要一个参数
print(MyClass.foo())
Traceback (most recent call last):
File "d:/Doc/test.py", line 7, in <module>
print(MyClass.foo())
TypeError: foo() missing 1 required positional argument: 'self' #MyClass实例化后调用foo()方法;self指代当前实例本身,在这个示例中self表示的就是MyClass();
#可以这理解,当MyClass()实例调用foo()方法的时候,self=MyClass(),也就是foo(MyClass())
print(MyClass().foo())
My Class #__doc__也是类的属性
print(MyClass.__doc__)
A example class #每实例化出一个对象,都可以和方法做绑定,也就是说多个对象可以绑定一个方法;他们在内存中的地址是不一样的;
a = MyClass()
print(MyClass().foo)
print(a.foo)
print(hex(id(a.foo)))
<bound method MyClass.foo of <__main__.MyClass object at 0x000001C3E93A5C40>>
<bound method MyClass.foo of <__main__.MyClass object at 0x000001C3E9376B50>>
0x1c3e8ed3100 #一个是通过实例访问,一个是通过类访问;
print(a.foo) #MyClass类对象的内存地址
print(MyClass.foo) #函数对象的内存地址
<bound method MyClass.foo of <__main__.MyClass object at 0x00000246CBD86B50>>
<function MyClass.foo at 0x00000246CBDC9F70>
#前后都有下划线的方法称为魔术方法,init可以理解为初始化方法,当构建一个实例的时候都会去执行这个方法
class Persion:
def __init__(self,name):
print(name) p = Persion()
print(p)
TypeError: __init__() missing 1 required positional argument: 'name' p1 = Persion('tom')
print(p1)
tom
<__main__.Persion object at 0x000002152D9E5C40>
#############################
面向对象代码执行过程:
class Horse:
nose="鼻子"
eye="眼睛"
def __init__(self,name,age):
self.name = name
self.age = age
def showname(self):
print('{} is {} 有 {} 有 {}'.format(self.name,self.age,self.nose,self.eye)) whitehorse = Horse('whitehorse',18)
darkhorse = Horse('darkhorse',19) whitehorse.showname()
darkhorse.showname()
print(darkhorse.age)
darkhorse.age += 1
print(darkhorse.age)
'''
执行结果:
whitehorse is 18 有 鼻子 有 眼睛
darkhorse is 19 有 鼻子 有 眼睛
19
20
'''
1、首先在内存中定义一个Horse的类对象,在这个类对象中捆绑一个__init__的属性,生成一个归类对象Horse管理的函数;
2、对Horse这个类做实例化操作,创建两个实例,whitehorse和darkhorse;执行__init__函数,与创建的实例建立关系;
3、whitehorse/darkhorse再去调用showname方法,showname方法再调用实例变量和类变量打印结果;
实例化
baima = Horse('baima','18')
heima = Horse('heima','19')
实例化就是真正创建一个该类的对象,baima和heima就是Horse类的实例;每次实例化后获得的实例,都是不同的实例,即使使用同样的参数实例化,得到的也是不一样的对象;python类实例化后,会自动调用__init__方法;这个方法的第一个参数必须留给self,其他参数随意;
__init__方法
ClassName实际上调用的是__init__(self)方法,可以不定义,如果没有定义会在实例化后隐式调用;
作用:对实例进行初始化;
class ClassName:
def __init__(self):
print('init')
print(ClassName) #未调用__init__
print(ClassName()) #临时创建一个对象,调用__init__
a = ClassName() #创建一个对象,并赋值给a,调用__init__;
初始化函数可以有多个参数,但是第一个位置必须留给self,self指代当前实例本身;
init方法被调用的时候,实例就已经存在了;self.name=表示给实例添加了个属性(因为self是一个实例,所以.name是实例的属性;)
注意:__init__方法不能有返回值,只能是None;其实隐式的在init下面有个return None;
class ClassName:
def __init__(self):
print('1','init')
return None #init方法不能有返回值,只能是None,隐式的在init方法内有一个return None,正常是可以不写的;
print('2',ClassName) #只返回了一个类,并没有产生实例,所以不调用init;
print('3',ClassName()) #实例化了一个类,所以调用了init,返回了结果;
a = ClassName() #同样的道理,实例化了一个类,调用了init,返回了结果
'''
执行结果:
2 <class '__main__.ClassName'>
1 init
3 <__main__.ClassName object at 0x0000020C4A8B6B50>
1 init
'''
class ClassName:
def __init__(self):
return 1 print(ClassName()) '''
执行结果:
Traceback (most recent call last):
File "d:/Doc/test.py", line 13, in <module>
print(ClassName())
TypeError: __init__() should return None, not 'int'
进一步证明了在init方法中不能有返回值;
'''
self
class MyClass:
def __init__(self):
print('self in init = {}'.format(id(self))) c = MyClass() #会调用__init__
print("c = {}".format(id(c))) '''
打印结果:
self in init = 1653473318728
c = 1653473318728 在真正调用init的时候,其实实例就已经存在了,所以id(self)能取到值;所以前后两个的id值是一样的;进一步说明了self指代的是实例本身;
'''
实例对象instance
类实例化后一定会获得一个对象,就是实例对象;
Horse是定义一个类,Horse()创建一个实例,并实例化,baima=Horse()将实例化的值赋给白马,baima就是Horse类的实例对象;
__init__方法的第一个参数self就是指代某一个实例,这个self就是上述例子中的baima,python会把方法的调用者作为第一参数self的实参传入;
类实例化后,得到一个实例对象,实例对象会绑定方法,调用方法时采用baima.showname()的方式;
self.name就是baima对象的name,name是保存在了baima对象上,而不是Horse类上,所以称为实例变量;
实例变量和类变量
实例变量是每一个实例自己的变量,是自己独有的;类变量是类的变量,是类的所有实例共享的属性和方法;
特殊属性 含义
__name__ 对象名
__class__ 对象的类型
__dict__ 对象的属性的字典
__qualname__ 类的限定名
注意:python中每一种对象都拥有不同的属性;函数、类都是对象,类的实例也是对象;
class Person:
age = 5
def __init__(self,name):
self.name = name
#self.age = age
def showage(self):
print('{} is {}'.format(self.name,self.age)) t = Person('tom')
t.showage() #age属于类变量,当实例没有age属性的时候就问类去要;
print(Person.age) ##age属于类变量
Person.age = 30 #为类变量重新赋值
print(t.age) #原则是一样的,当实例没有的时候问类要;
t.showage()
'''
执行结果:
tom is 5
5
30
tom is 30
'''
class Person:
"""hello"""
age = 5
def __init__(self,name:str): #init方法一旦被调用,则实例已经存在了;
self.name = name #给实例添加属性,因为目前self代表的是一个实例;则这是实例的属性;而不是类的属性;
self.age = 18
def showage(self):
pass print(1,sorted(Person.__dict__.items())) tom = Person('tom')
print(2,tom.__class__)
print(3,sorted(tom.__dict__.items()))
print(3.1,tom.__dict__)
print(4,sorted(tom.__class__.__dict__.items()))
print(5,Person('jerry').__dict__)
print(6,tom.age)
print(7,tom.__class__.age)
print(8,type(tom).age)
print(9,Person.age)
######
print(Person.__class__) #类类型的对象
print(Person.__class__.__name__) #类类型的名称
print(Person('jerry').__class__) #问这个实例的类是谁
print(Person('jerry').__class__.__name__) #这个实例的类的名字是什么
# 执行结果
PS D:\Doc> & D:/Python/Python38/python.exe d:/Doc/test.py
1 [('__dict__', <attribute '__dict__' of 'Person' objects>), ('__doc__', 'hello'), ('__init__', <function Person.__init__ at 0x00000243FDE79F70>), ('__module__', '__main__'), ('__weakref__', <attribute '__weakref__' of 'Person' objects>), ('age', 5), ('showage', <function Person.showage at 0x00000243FDE8A040>)]
2 <class '__main__.Person'>
3 [('age', 18), ('name', 'tom')]
3.1 {'name': 'tom', 'age': 18}
4 [('__dict__', <attribute '__dict__' of 'Person' objects>), ('__doc__', 'hello'), ('__init__', <function Person.__init__ at 0x00000243FDE79F70>), ('__module__', '__main__'), ('__weakref__', <attribute '__weakref__' of 'Person' objects>), ('age', 5), ('showage', <function Person.showage at 0x00000243FDE8A040>)]
5 {'name': 'jerry', 'age': 18}
6 18
7 5
8 5
9 5
上例中,可以看到类属性保存在类的__dict__中,实例属性保存在实例的__dict__中,如果从实例访问类的属性,就需要借助__class__找到所属的类;
实例属性的查找顺序
指的是实例使用"."来访问属性,会先找自己的__dict__,如果没有,然后通过属性__class__找到自己的类,再去类的__dict__中找;
注意,如果实例使用__dict__[变量名]访问变量,将不会按照上面的查找顺序找变量了,这是指明使用字典的key查找,不是属性查找;
第十四天python3 面向对象的更多相关文章
- 大数据笔记(二十四)——Scala面向对象编程实例
===================== Scala语言的面向对象编程 ======================== 一.面向对象的基本概念:把数据和操作数据的方法放到一起,作为一个整体(类 c ...
- JavaScript(第十四天)【面向对象和原型】
学习要点: 1.学习条件 2.创建对象 3.原型 4.继承 ECMAScript有两种开发模式:1.函数式(过程化),2.面向对象(OOP).面向对象的语言有一个标志,那就是类的概念,而通过类可以创建 ...
- 第三十四篇 Python面向对象之 反射(自省)
什么是反射? 反射的概念是由Smith在1982年提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它首先被程序语 ...
- 第十四节 JS面向对象基础
什么是面向对象:在不需要知道它内部结构和原理的情况下,能够有效的使用它,比如,电视.洗衣机等也可以被定义为对象 什么是对象:在Java中对象就是“类的实体化”,在JavaScript中基本相同:对象是 ...
- python入门(十四):面向对象(属性、方法、继承、多继承)
1.任何东西1)属性(特征:通常可以用数据来描述)(类变量和实例变量)2)可以做一些动作(方法) 类来管理对象的数据.属性:类变量和实例变量(私有变量)方法: 1)实例方法 2)类方法 ...
- python系列十六:Python3 面向对象
#!/usr/bin/python #-*-coding:gbk-*- #Python3 面向对象 '''面向对象技术简介 类(Class): 用来描述具有相同的属性和方法的对象的集合.它定义了 ...
- python系列十四:Python3 文件
#!/usr/bin/python #Python3 文件 from urllib import requestimport pprint,pickle'''读和写文件open() 将会返回一个 fi ...
- java 面向对象(十四):面向对象的特征二:继承性 (三) 关键字:super以及子类对象实例化全过程
关键字:super 1.super 关键字可以理解为:父类的2.可以用来调用的结构:属性.方法.构造器3.super调用属性.方法:3.1 我们可以在子类的方法或构造器中.通过使用"supe ...
- python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例
python3.4学习笔记(十四) 网络爬虫实例代码,抓取新浪爱彩双色球开奖数据实例 新浪爱彩双色球开奖数据URL:http://zst.aicai.com/ssq/openInfo/ 最终输出结果格 ...
随机推荐
- viewport布局
1.viewport实例 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <h ...
- 【机器学习基础】无监督学习(3)——AutoEncoder
前面主要回顾了无监督学习中的三种降维方法,本节主要学习另一种无监督学习AutoEncoder,这个方法在无监督学习领域应用比较广泛,尤其是其思想比较通用. AutoEncoder 0.AutoEnco ...
- Redis GEO 地理位置
目录 GEO指令 GEOADD GEODIST GEOPOP GEOHASH GEORADIUS GEORADIUSBYMEMBER 指令补充 删除操作 避免单集合数量过多 存储原理 GEOADD存储 ...
- k8s的api资源
NAME SHORTNAMES APIGROUP NAMESPACED KIND 资源用途说明 bindings TRUE Binding 已弃用.用于记录一个object和另一个object ...
- 前端CSS3动画animation用法
前端CSS3动画animation用法 学习如下动画属性 @keyframes animation-name animation-duration animation-delay animation- ...
- JAVA - 请说明”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?
请说明"static"关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法? "static"关键字表明一个成 ...
- MySQL数据库5
内容概要 pyhton操作MySQL SQL注入问题 修改表SQL语句补充 视图.触发器.储存过程 事务 流程控制 函数 索引与慢查询优化 内容详情 pyhton操作MySQL python中支持操作 ...
- React项目配置npm run build命令分环境打包
使用create-react-app脚手架创建的项目默认隐藏了webpack等配置文件信息,使用npm run eject命令暴露这些隐藏的配置文件信息 项目默认有两个环境:开发环境(npm star ...
- TDSQL|三篇论文入选国际顶会SIGMOD,厉害了腾讯云数据库
好消息!6月13日,腾讯云数据库三篇论文再次入选数据库行业顶会SIGMOD,被SIGMOD 2022 Research Full Paper(研究类长文)收录. 本次被收录的研究成果中,新型数据结构设 ...
- 关于react的props你需要知道的一个简单方法
//注意一点:函数名必须大写 function Clock(props) { return ( <div> <h1>Hello, world!</h1> <h ...