python面向对象之类成员
面向对象编程:
OOP编程是利用类和对象来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得简单,并可以大大提高程序开发效率。另外,基于面向对象的程序可以使他人更容易理解代码逻辑,从而使团队开发变得更容易。
Class类:
一个类即是一个类的实例化后实例,一个类必须经过实例化后方可在程序中调用,一个类可以实例化成多个对象,每个对象亦可以有不同的属性,就像人类是指所有人,每个人指具体的对象,人与人之间有共性亦有不同。
Encapsulation封装:
在类中对数据的赋值、内部调用对外部用户是透明的,这使类变成了一个胶囊容器,里面包含着类的数据和方法。
Inheritance继承:
一个类可以派生出子类,在这个父类里定义的属性、方法自动被子类继承。
Polymorphism多态:
多态是面向对象的重要特性,简单说:‘一个接口,多种实现’。指一个基类中派生出了不同的子类,且每个子类在继承同样的方法名的同时又对父类的方法做了不同的实现,这就是同一种事物表现出的多种形态。
编程其实就是一个将具体世界进行抽象化得过程,多态就是抽象化得一种体现,把一系列具体事物的共同点抽象出来,再通过这个抽象的事物,与不同的具体事物进行对话。
对不同类的对象发出相同的消息将会有不同的行为。比如,你的老板让所有员工再九点钟开始工作,他只要在九点钟的时候说开始工作即可,而不需要对销售人员说开始销售工作,对技术人员说开始技术工作。因为员工是一个抽象的事物,只要是员工就可以开始工作,他知道这一点就行了。至于每个员工,当然各司其职。
多态允许将子类的对象当作父类的对象使用,某父类的引用指向其子类的对象,调用方法是该子类的方法。这里引用调用方法的代码编译前就已经决定了,而引用所指向的对象可以在运行期间动态绑定。
面向对象:
面向对象是一种编程方式,此编程方式的实现是基于对类和对象的使用
类是一个模板,模板中包装了多个函数供使用(可以将多函数中公用的变量封装到对象中)
对象是根据模板创建的实例,实例用于调用被包装在类中的函数
三大特性为:封装、继承、多态
类的成员可分为三大类:字段、方法和属性
字段:普通字段、静态字段
方法:普通方法、类方法、静态方法
属性:普通属性
PS:所有成员中,只有普通字段的内容保存在对象中,即,根据此类创建了多少对象,在内存中就有多少个普通字段。而其他的成员,则都是保存在类中,即无论对象的多少,在内存中只创建一份。
一、字段
字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同。
普通字段属于对象,静态字段属于类。
class Province(object):
country = '中国' #静态字段 def __init__(self, name):
self.name = name #普通字段 obj = Province('山东') #直接访问普通字段
print(obj.name)
print(Province.country) #直接访问静态字段
由上可看出普通字段需要通过对象来访问,静态字段通过类访问。在使用上可以看出普通字段和静态字段的归属是不同的,其在内容的存储方式类似如下:
由上图可以看出 静态字段在内存中只保存一份,普通字段在每个对象中都要保存一份
应用场景:通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段
二、方法:
方法包括:普通方法,静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
普通方法:由对象调用,至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self。
类方法: 由类调用,至少一个cls参数;执行类方法时,自动将调用该方法的类赋值给cls。
静态方法:由类调用,无默认参数。
class Foo(object): def __init__(self, name):
self.name = name def ord_func(self): #定义普通方法,至少需要self参数
print('普通方法', self.name) @classmethod
def cls_func(cls): #定义类方法,至少需要cls参数
print('类方法', cls) @staticmethod
def sta_func(): #定义静态方法,无默认参数
print('静态方法') obj = Foo('cab')
obj.ord_func() #调用普通方法 Foo.cls_func() #调用类方法 Foo.sta_func() #调用静态方法
相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份
不同点:方法调用者不同,调用方法时自动传入的参数不同。
三、属性
1、属性的基本使用
class Foo(object):
def func(self):
print('func', self.prop) @property
def prop(self): #定义属性
print('property') obj = Foo() obj.func()
obj.prop #调用属性
由属性的定义和调用要注意以下几点:
定义时,在普通方法的基础上添加property装饰器;属性仅有一个self参数;调用时,无需括号
方法的调用:obj.func() 属性的调用:obj.prop
属性的存在意义是:访问属性时可以制造出和访问字段完全相同的假象。属性由方法变种而来,如果python中没有属性,方法完全可以代替其功能。
示例: 对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示指定获取从第m条到第n条的所有数据(即:limit m,n),这个分页的功能包括:根据用户请求的当前页和总数据条数计算出m和n; 根据m和n去数据库中请求数据。
class Paper(object):
per_item = 10 #定义每页显示的条数 def __init__(self, current_page):
self.current_page = current_page #输入当前页数 @property
def start(self):
value = (self.current_page - 1) * self.per_item + 1
return value #返回当前页的起始条
def end(self):
value = self.current_page * self.per_item
return value #返回当前页的结束条
bar = property(end) obj = Paper(2)
print(obj.start)
print(obj.bar) #自动调用bar方法,并获取方法的返回值
由上述可见,python的属性的功能是:属性内部进行一系列的逻辑计算,最终将计算结果返回。
2、属性的两种定义方式:
装饰器方式:即在方法上应用装饰器property
静态字段方式:在类中定义值为property对象的静态字段。(比如上例中的bar对象)
装饰器方式:在类的普通方法上应用@property装饰器,在上例中应用的是经典类,即具有一种@property装饰器。
一下介绍一下新式类:
class Foo(object):
@property
def price(self):
print('古典类property') @price.setter
def price(self, value):
print(value) @price.deleter
def price(self):
print('新式类之deleter') @price.getter
def price(self):
print('新式类之getter')
obj = Foo()
obj.price
#自动执行@price.getter修饰的price方法,并获取@price.getter方法的返回值
#如果没有@price.getter的修饰,则执行@property修饰的price方法,并返回
obj.price = 222
#自动执行@property修饰的price方法,并将222赋值给方法的参数 del obj.price #自动执行@price.deleter修饰的price方法
PS:经典类中的属性只有一种访问方式,其对应被@property修饰的方法。新式类中的属性由三种访问方式,并分别对应了三个被@property、@方法名.setter、@方法名.deleter、@方法名.getter修饰的方法
由于新式类中具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同意个属性:获取、修改、删除。
class Goods(object):
def __init__(self, price, sale):
self.old_price = price #原价
self.sale = sale #折扣 @property
def cost(self):
new_price = self.old_price * self.sale #实际价格
print('new_price:', new_price)
return new_price @cost.setter
def cost(self, price):
self.old_price = price
print(self.old_price) @cost.deleter
def cost(self):
del self.old_price obj = Goods(100, 0.8)
obj.cost #获取价格
obj.cost = 200 #定义价格
del obj.cost #删除价格
静态字段方式,创建值为property对象的静态字段,当时用静态字段的方式创建属性时,经典类和新式类无区别。
class Foo(object):
def get_bar(self):
print('cab')
return 111 bar = property(get_bar) obj = Foo()
res = obj.bar #自动调用get_bar方法,并获取方法的返回值
print(res)
property的构造方法中有四个参数:
- 第一个参数是方法名,调用
对象.属性
时自动触发执行方法 - 第二个参数是方法名,调用
对象.属性 = XXX
时自动触发执行方法 - 第三个参数是方法名,调用
del 对象.属性
时自动触发执行方法 - 第四个参数是字符串,调用
对象.属性.__doc__
,此参数是该属性的描述信息
class Foo(object):
def get_bar(self):
return 'cab' def set_bar(self, value):
return value def del_bar(self):
return 111 BAR = property(get_bar, set_bar, del_bar, 'description...') obj = Foo() obj.BAR #自动调用第一个参数中的get_bar方法
obj.BAR = 222 #自动调用第二个参数中的set_bar方法,并修改为222
del obj.BAR #自动调用第三个参数中的del_bar方法
obj.BAR.__doc__ #自动获取第四个参数的值
定义属性由两种方式,分别是装饰器和静态字段,而装饰器方式针对经典类和新式类又有不同。
python面向对象之类成员的更多相关文章
- Python面向对象之成员修饰符
对于这些类成员有修饰符 之前定义字段country任何对象都可以访问,是公有的 可以定义为私用属性,只有类内部的方法可以调用,外部不能直接调用,但是可以间接调用 vim day7-10.py #!/u ...
- python面向对象之类成员修饰符
类的所有成员分为: 公有成员,在任何地方都能访问 私有成员,只有在类的内部才能访问 私有成员和公有成员的定义不同:私有成员命名时,前两个字符是下划线.(特殊成员除外,例如:__init__.__c ...
- Python面向对象-类成员
类的成员可以分为三大类:字段.方法和属性: 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,则都是保存在类中,即:无论对象的多少,在 ...
- python 面向对象(二)成员
##################################总结########################### 类的成员: 变量: 实例变量 对象.属性=xxx 类变量 ...
- Python面向对象(特殊成员)
day25 __init__ 类()自动执行 __del__ __call__ 对象() 类()() 自动执行 __int__ int(对象) ...
- python 面向对象类成员(字段 方法 属性)
一.字段 字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同, 普通字段属于对象 静态字段属于类 class Province: # 静态字段 countr ...
- python面向对象的成员、属性等
#类成员: #字段 self.xy =qq . xy=qq #普通字段 (保存在对象里面) #直接通过点(.)+ 字段 进行调用 #静态字段 (保存在类里面) #静态字段属于类,在内存只保留一份 . ...
- python面向对象(二)——类成员
Python面向对象 类成员 1.字段 普通字段 属于对象 静态字段 属于类 2.方法 普通方法 触发者是对象 括号里至少一个参数 se ...
- python 面向对象和类成员和异常处理
python 面向对象 你把自己想象成一个上帝,你要创造一个星球,首先你要把它揉成一个个球,两个直径就能创造一个球 class star: '''名字(name),赤道直径(equatorial di ...
随机推荐
- lazy初始化和线程安全的单例模式
1.双检锁/双重校验锁(DCL,即 double-checked locking) JDK 版本:JDK1.5 起 是否 Lazy 初始化:是 是否多线程安全:是 实现难度:较复杂 描述:这种方式采用 ...
- IOS TableView实现省市联动
之前用UIPickerView实现了省市联动,上个月网友让用UITableView给他实现了下.今天也把这些贴出来. // // ViewController.m // doubleTable // ...
- 在方法中new关键字的用处
如果在类A中有M1这个方法需方法 public virtual ovid m1() { console.writeline(“我的世界”); } 那么你在类B中继承的时候可以重写这个方法,也可以不重写 ...
- Quartz大致介绍(一)
1. 介绍 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳 ...
- Google Voice号码使用说明及用途
Google Voice号码使用说明及用途 号码 已不能网页注册获取,直接向TB购买,搜Google Voice就行了.很便宜的. 一. Google Voice介绍 Google Voice首先是一 ...
- OutOfMemoryError(内存溢出)解决办法
第一种OutOfMemoryError: PermGen space 发生这种问题的原意是程序中使用了大量的jar或class,使java虚拟机装载类的空间不够,与Permanent Generati ...
- 从MySQL到ORM(二):MySQL基础
一.基本概念 1.数据库: 数据库(DataBase)就是一个存储数据的仓库,为了方便数据的存储和管理,它将数据按照特定的规律存储在磁盘上.通过数据库管理系统,可以有效的组织和管理存储在数据库中的数据 ...
- HDU 1757 矩阵求第n的递推式
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- springmvc 框架原理
先来个原理图,镇博. (图片出处:http://www.cnblogs.com/selene/p/4658554.html,感谢博主的图) 着重看:处理器映射器,处理器适配器,这两个的配置. 这两个的 ...
- CakePHP Configure::read('KHCITY') 数据配置读取
1. 2.引入 循环遍历 正确: