Python3 学习第五弹:类与面向对象

对于面向对象总是要提到,万物皆对象。好似博大精深的感觉。
接下来一起看看python的面向对象的例子

创建一个对象

	class Person:
		type = ‘person‘
		def __init__(self, name = ‘Noname‘):
			self.name = name
		def hello(self):
			print("hello, I‘m " + self.name)
	>>> Mike = Person(‘Mike‘)
	>>> Mike.hello()
	hello, I‘m Mike
	对于一个对象,均会有默认构造方法,当然我们可以通过重写__init__来改变构造方法。当一个对象创建时会自动调用构造方法。

类的属性

	类属性:type以及默认类属性
	实例属性:name
	很容易理解,实例属性只有当创建一个类对象时才会产生,而类属性是类固有的属性
	类属性访问可以通过dir(Person)或Person.__dict__查看
	而实例属性可以通过Mike.__dict__查看

	基本类属性:
	__doc__	函式的文档. 字符串, 如果没有 的话就为 None	可写
	__name__	函式名	可写
	__module__	定义函式的模块名, 或者如果没有 对应模块名, 就为 None
	__bases__ 返回该类的所有父类构成的元组
	__class__ 实例所对应的类
	__dict__ 类的属性构成的字典

	>>> class Person:
		‘‘‘Michael Scofield‘s file‘‘‘
		name = ‘Michael‘
		def __init__(self, age):
			self.age = age
	>>> Person.__doc__
	"Michael Scofield‘s file"
	>>> Person.__name__
	‘Person‘
	>>> Person.__bases__
	(<class ‘object‘>,)
	>>> Person.__dict__
	mappingproxy({‘__dict__‘: <attribute ‘__dict__‘ of ‘Person‘ objects>, ‘__doc__‘: "Michael Scofield‘s file", ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Person‘ objects>, ‘name‘: ‘Michael‘, ‘__module__‘: ‘__main__‘, ‘__init__‘: <function Person.__init__ at 0x00000000033DBBF8>})
	>>> a = Person(30)
	>>> a.__class__
	<class ‘__main__.Person‘>

继承的应用

	子类可以通过继承来获得父类的属性,此外可以有自己的类属性
		>>> class Bird:
			def __init__(self):
				self.hungry = True
			def eat(self):
				if self.hungry:
					print(‘eat something‘)
					self.hungry = False
				else:
					print(‘Too fat‘)
		>>> class SongBird(Bird):
			def __init__(self, song):
				self.song = song
			def sing(self):
				print(self.song)
		>>> a = SongBird(‘hello‘)
		>>> a.sing()
		hello
	我们常常会遇到子类有父类的相似函数,但是又不太一样。就可以通过重写来建立自己的函数,在运行该函数的时候会先在子类中找该函数,若无再从父类中寻找,例如上例中的__init__方法重写
	但是又会出现一个问题,
		>>> a.eat()
		AttributeError: ‘SongBird‘ object has no attribute ‘hungry‘
	由于没有调用到父类的init使得hungry的属性消失,这时候利用super可以消除这种影响。
		>>> class SongBird(Bird):
				def __init__(self, song):
					super(SongBird, self).__init__()
					self.song = song
		>>> a.eat()
		eat something
		>>> a.eat()
		Too fat
	这里的super不是一个函数,而是一个类,表示SongBird的父类并传入自身对象self
	当然在出现super之前有另一个解决办法,就是直接调用父类的函数
		>>> class SongBird(Bird):
				def __init__(self, song):
					Bird.__init__(self)
					self.song = song
	但是由于一旦改动其父类,需要每次改变该类中的父类如上例中的Bird,因此最好使用super

类方法(类似于操作符重载)

	像上面例子中的__init__就是构造方法,当创建一个新类对象时自动调用,此外,还有许多可供使用的类方法,几乎覆盖了python所有操作符。
	接下来我们来看一看常见的类方法。

	>>基本方法:

	1> __init__(self[, arg1, ...]) 构造函数,在函数对象创建后调用,无返回值

	2> __new__(self[, arg1, ...]) 构造函数,创建函数对象的函数,返回值即该对象
	一般来说__new__不会被用到,除非子类需要不可变类型时才会用到。

	3> __del__(self) 在对象删除时调用,一般不改变,因为对象删除的时间由python自身决定

	4> __str__(self) 返回要打印的字符串(对用户较为友好),内建有str()及print

	5> __repr__(self) 返回对编译器友好的字符串,对细节处理上略有不同

	repr 与 str 区别:
		The str() function is meant to return representations of values which are fairly human-readable, while repr() is meant to generate representations which can be read by the interpreter (or will force a SyntaxError if there is not equivalent syntax). For objects which don‘t have a particular representation for human consumption, str() will return the same value as repr(). Many values, such as numbers or structures like lists and dictionaries, have the same representation using either function. Strings and floating point numbers, in particular, have two distinct representations.

	6> __format__(self, format_spec) 调用format()运行该函数

	7> __call__(self, *args) 类可以当作函数来调用,每次调用这个类对象时会运行,相当于重载了括号

	8> __len__(self) 在调用len()时会运行会运行该函数

	>>比较方法:

	1> __lt__(self, obj) 重载 <

	2> __le__(self, obj) 重载 <=

	3> __eq__(self, obj) 重载 ==

	4> __ne__(self, obj) 重载 !=

	5> __gt__(self, obj) 重载 >

	6> __ge__(self, obj) 重载 >=

	其中若不重载>, >默认会与<的对象交换,反之相同

	>>> class Person:
		def __init__(self, age):
			self.age = age
		def __lt__(self, b):
			return self.age - b.age
		def __gt__(self, b):
			return self.age > b.age
	>>> a = Person(1)
	>>> b = Person(2)
	>>> a > b
	False
	>>> a < b
	-1
	>>> b > a
	True
	>>> b < a
	1

	>>属性操作方法
	(注意以下的attr属性都是用字符串表示)

	1> __getattr__(self, attr) 获取属性不成功时调用,使用getattr()时调用(很奇怪在用python3测试时,即使获取属性成功也调用了)

	2> __setattr__(self, attr, value) 设置属性或新建属性时调用,使用setattr()时调用

	>>> class Person:
		def __init__(self, age):
			self.age = age
		def __getattr__(self, attr):
			print(‘__getattr__ used‘)
		def __setattr__(self, attr, val):
			print(‘__setattr__ used‘)
	>>> a = Person(1)
	__setattr__ used
	>>> a.age
	__getattr__ used
	>>> a.age=1
	__setattr__ used

	3> __delattr__(self, attr) 删除属性,使用delattr()调用

	4> __getattribute__(self, attr) 获取属性时无论访问成功与否都调用

	5> __get__(self, attr) 描述器,获取属性
	6> __set__(self, attr, value) 描述器,设置属性
	7> __delete__(self, attr) 描述器 删除属性
		以上三个暂时不明白其用法

	>> 数值运算符号重载

	1> __add__(self, other) 重载+
	2> __sub__(self, other) 重载-
	3> __mul__(self, other) 重载*
	4> __truediv__(self, other) 重载/
	5> __floordiv__(self, other) 重载//
	6> __mod__(self, other) 重载%
	7> __divmod__(self, other) 重载divmod(a, b) #返回元组(a//b, a%b)
	8> __pow__(self, other[, modulo]) 重载pow(a, b) **
	9> __lshift__(self, other) 重载<<
	10> __rshift__(self, other) 重载>>
	11> __and__(self, other) 重载&
	12> __xor__(self, other) 重载^
	13> __or__(self, other) 重载|

	ADD1:
		若在上述重载计算操作符函数前加入r,即__radd__(self, other),则表示其参数位置对调。
		例如, 计算表达式 x - y, y 是一个定义了方法 __rsub__() 的类实例, 那么在 x.__sub__(y) 返回 NotImplemented 时才会调用 y.__rsub__(x).
	ADD2:
		若在上述重载计算操作符函数前加入i,即__iadd__(self, other),则该重载符为 += 。以此类推

	14> __neg__(self) 重载负号-
	15> __pos__(self) 重载正号+
	16> __abs__(self) 重载abs()
	17> __invert__(self) 重载^

	强制转换类型
	18> __complex__(self) 重载complex() #表示复数类型
	19> __int__(self) 重载int()
	20> __float__(self) 重载float()
	21> __round__(self) 重载round()

	>>序列操作符重载

	1> __len__(self) 序列中项的个数

	2> __getitem__(self, index) 获取序列时调用

	3> __setitem__(self, index, value) 设置序列项或者新建项时调用

	4> __delitem__(self, index) 删除单个序列元素时调用

	>>> class Class:
		def __init__(self):
			self.student = [‘LWT‘, ‘CYL‘, ‘Bash‘]
		def __len__(self):
			print(‘len called‘)
			return len(self.student)
		def __getitem__(self, index):
			print(‘getitem called‘)
			return self.student[index]
		def __setitem__(self, index, value):
			print(‘setitem called‘)
			self.student[index] = value
		def __delitem__(self, index):
			print(‘delitem called‘)
			del self.student[index]
	>>> a609 = Class()
	>>> len(a609)
	len called
	3
	>>> a609[1]
	getitem called
	‘CYL‘
	>>> a609[2] = ‘Bug‘
	setitem called
	>>> a609
	<__main__.Class object at 0x0000000003C3FD30>
	>>> del a609[2]
	delitem called

	其实就相当于对列表进行重载其操作。

	以上,大概包括了大部分的重载类型。

  

时间: 2024-10-17 20:09:04

Python3 学习第五弹:类与面向对象的相关文章

前端学习 第五弹: CSS (一)

前端学习 第五弹: CSS (一) 创建css: <link rel="stylesheet" type="text/css" href="mystyle.css" /> 外联 <style type="text/css"> hr {color: sienna;} p {margin-left: 20px;} body {background-image: url("images/back40

JAVA学习(五):Java面向对象编程基础

Java面向对象编程基础 面向对象(Object oriented programming,OOP)技术是一种强有力的软件开发方法,它採用数据抽象与信息隐藏技术,来使软件开发简单化,以达到代码重用的目的. 1.OOP的3个特性(封装.继承和多态性) 封装是类的基础.指把类的相关实现细节隐藏起来,在类中将数据和实现操作的代码集中起来放在对象的内部.调用这些类时仅仅需直接使用类预留的接口就能够了. 继承提供了子类自己主动拥有父类数据结构和方法的机制.它表示类之间的一种关系. 多态指使一个对象被看成还

JAVA学习第五天 - 类与对象

一.面向对象程序设计的基本概念 1,对象: 特征分为静态特征和动态特征.静态特征指对象的外观.性质.属性等,动态特征指对象具有的功能.行为等.客观事物是错中复杂的,但是人们总是从某一目的出发,运用抽象分析的能力,从总舵的特征中抽取最具代表性.最能反映对象本质的若干特征加以详细研究. 人们讲将对象的静态特征抽象为属性,用数据来描述,在Java语言中成为变量:人们将对象的动态特征抽象为行为,用一组代码表示,完成对数据的操作,在Java语言中成为方法.一个对象由一组属性和一组对属性进行操作的方法构成.

Python3 学习第八弹: 模块学习一之模块变量

__name__变量 用于判断该python文件是否作为主程序运行.若该文件为导入,__name__值为其文件名,若为主程序,则其值为__main__ 这也就是为什么经常看到有一些python文件中有 if __name__ == '__main__' 的字样,就是为了防止导入时把该文件里面的主程序也运行. __all__变量 定义了模板的共有接口,比如 from os import * 这其中*代表的就是你只能利用__all__变量中的函数,像__all__变量是有相当用处的,因为模板中可能有

Python3 学习第十三弹: 模块学习六之re模块 + 正则表达式 (转)

本文转自 AstralWind 的博客:Python正则表达式指南 特来收藏 1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大.得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同:但不用担心,不被支持的语法通常是不常用的部分.如果已经在其他语言里使用过正则表达式,只需要简单看

Python3 学习第十弹: 模块学习三之数字处理

math模块 提供基础的数学函数, cos(3.14) = -0.999..(弧度制) acos(1) = 0.0 sqrt(9) = 3.0 degrees(3.14) = 179.9999..(弧度转角度) radians(180) = 3.1415926..(角度转弧度) 常量 pi = 3.1415.. e = 2.7182.. cmath模块(complex math, 复数) 支持复数的运算, >>>import cmath >>>cmath.sqrt(-1

Python3 学习第十一弹: 模块学习四之sys库

sys模块 提供一些与python解释器关系紧密的变量和函数 1> argv 命令行参数 通过命令行可以向python传输参数 2> exit([arg]) 程序退出,可以返回给命令行一个错误参数或返回值 ## test.py ## import sys i = 0 for argv in sys.argv: print('第', i, '个参数: ', argv) i += 1 exit(argv) 3> path 一个存储Python基本源模块的路径的列表,可以自行添加自定义模块路径

C#学习第五弹之正则表达式初探

正则表达式使用单个字符串来描述.匹配一系列符合某个句法规则的字符串.在很多文本编辑器里,正则表达式通常被用来检索.替换那些符合某个模式的文本. 许多编程语言都支持正则表达式,C#也不例外,下面让我们来初探正则表达式. 首先是元字符,即在正则表达式中具有特殊意义的一些专用字符,可以用一个或一组元字符来代替一个或一组字符,常见元字符如下: 然后是限定符,对之前的字符进行限定,常见的限定符如下: 转义字符:注意到元字符本身有可能成为被查找对象或被查找对象的一部分,于是出现了转义的概念.和C++中的转义

css学习の第五弹—单位和值

一. >>1.颜色表示方法总结: 1.英文命令颜色 前面几个小节中经常用到的就是这种设置方法: p{color:red;} 2.RGB颜色 这个与 photoshop 中的 RGB 颜色是一致的,由 R(red).G(green).B(blue) 三种颜色的比例来配色. p{color:rgb(133,45,200);} 每一项的值可以是 0~255 之间的整数,也可以是 0%~100% 的百分数.如: p{color:rgb(20%,33%,25%);} 3.十六进制颜色 这种颜色设置方法是