## 属性的类型
  - 属性可分为类属性和实例属性

  - 实例属性可以通过在类中使用self定义,或者直接在类外部使用实例变量定义

 class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age per1 = Person("Stanley", 22)
print(per1.name) # 输出:Stanley
per1.weight = "50kg"
print(per1.weight) # 输出:50kg

  - 类属性则直接在类中定义
    - 类属性通过类名访问,也可以通过实例访问

 class Person(object):
class_name = "Person" def __init__(self, name, age):
self.name = name
self.age = age per1 = Person("Stanley", 22)
print(per1.class_name) # 输出:Person print(Person.class_name) # 输出:Person

  - 注意:
    - 如果实例属性和类属性使用了相同的名字,则实例化后实例属性将覆盖类属性,实例将无法在访问该同名类属性,而通过类名访问类属性将不受影响

 class Person(object):
name = "Person" def __init__(self, name, age):
self.name = name
self.age = age print(Person.name) # 输出:Person per1 = Person("Stanley", 22)
print(per1.name) # 输出:Stanley
print(Person.name) # 输出:Person

## 方法的类型
  - 在一个类中可以存在三种类型的方法
  - 在类的定义中,以self(即实例本身)作为第一个参数的方法为实例方法

 class Person(object):

     def __init__(self, name, age):
self.name = name
self.age = age # 这是一个实例方法,self为实例本身,作为第一个参数传入,通过实例调用
def eat(self):
print("I'm %s, I want to eat!" % self.name) per1 = Person("Stanley", 22)
per1.eat() # 输出:I'm Stanley, I want to eat!

  - 在类的内部定义,用修饰符@classmethod指定的方法是类方法
  - 类方法会作用于整个类,该方法对类做出的改变会影响该类的所有实例
  - 与实例方法类似,类方法的第一个参数是类本身,通常写作cls

class Person(object):
count = 0 def __init__(self, name, age):
self.name = name
self.age = age
Person.count += 1 # 每实例化一个对象,count加1 # 这是一个实例方法,self作为第一个参数传入,通过实例调用
def eat(self):
print("I'm %s, I want to eat!" % self.name) @classmethod # 使用@classmethod修饰
def kids(cls): # 第一个参数为类本身,这是一个类方法
print("class %s has %d instance(es)." % (cls.__name__, Person.count)) per1 = Person("Stanley", 22)
per2 = Person("Bob", 18)
per3 = Person("Lily", 17)
Person.kids() # 输出:class Person has 3 instance(es).

  - 第三种方法类型称为静态方法
  - 静态方法使用@staticmethod修饰,它不需要self参数或者cls参数
  - 静态方法的存在不会影响类也不会影响类的实例,仅仅是为了代码的逻辑性
  - 静态方法可以通过类名或者实例调用

 class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age @staticmethod
def say_hi():
print("I'm a static method. I say Hi.") per1 = Person("Stanley", 22)
per1.say_hi() # 输出:I'm a static method. I say Hi.
Person.say_hi() # 输出:I'm a static method. I say Hi.

## 使用property对attribute进行访问和设置
  - 对于一些语言比如Java来说,对于私有属性的访问需要使用setter和getter方法
  - Python不需要,因为Python所有属性都是公开的,但是也可以编写setter和getter限制对属性的访问

 class Person(object):
def __init__(self, name, age):
self.__name = name # 私有属性
self.age = age def set_name(self, name):
self.__name = name def get_name(self):
return self.__name per1 = Person("Stanley", 22)
print(per1.get_name()) # 输出:Stanley
per1.set_name("Lily") # 修改属性值
print(per1.get_name()) # 输出:Lily
print(per1.__name) # 无法直接访问私有属性,AttributeError: 'Person' object has no attribute '__name'

  - 以上写法达到了限制访问的目的

  - 但更Pythonic的写法是使用property()

 class Person(object):
def __init__(self, name, age):
self.__name = name
self.age = age def set_name(self, name):
self.__name = name def get_name(self):
return self.__name # 使用property函数将getter和setter定义为了name属性
name = property(get_name, set_name) per1 = Person("Stanley", 22)
print(per1.name) # 访问属性时自动调用getter方法,输出:Stanley
per1.name = "Lily" # 设置属性时自动调用setter方法
print(per1.name) # 输出:Lily
print(per1.get_name()) # 也可以显式的调用getter或者setter方法

  - 还有一种方法进行访问限制,那么就是使用修饰符,并定义两个同名方法

 class Person(object):
def __init__(self, name, age):
self.__name = name
self.age = age @property # @property 用于指示getter方法
def name(self): # 两个同名函数
return self.__name @name.setter # @name.setter 用于指示setter方法
def name(self, name): # 两个同名函数
if isinstance(name, str):
self.__name = name
else:
raise TypeError("Name must be string!") per1 = Person("Stanley", 22)
print(per1.name) # 输出:Stanley
per1.name = "Lily"
print(per1.name) # 输出:Lily

  - 使用了@property修饰的方法就变成了属性

 import datetime

 class Person(object):
def __init__(self, name, age):
self.__name = name
self.age = age @property
def birth_year(self):
return datetime.datetime.now().year - self.age per1 = Person("Stanley", 22)
print(per1.birth_year) # 输出:1996
per1.birth_year = 2000 # 没有指定setter属性(@birth_year.setter),所以无法从外部对它的值进行设置,这使得这个birth_year这个属性成为只读属性

本文参考:

  [美]Bill Lubanovic 《Python语言及其应用》

Python面向对象--高级(一)的更多相关文章

  1. python 面向对象高级应用(三)

    目录: isinstance(obj,cls)和issubclass(sub,super) 反射 __setattr__,__delattr__,__getattr__ 二次加工标准类型(包装) __ ...

  2. Python学习笔记【第十一篇】:Python面向对象高级

    isinstance(obj,cls)和issubclass(sub,super) class Person(object): def __init__(self, name, age, sex, n ...

  3. python面向对象高级:Mixin多重继承

    继上一篇学习笔记:python面向对象的继承与多态,本篇就Mixin扩展类的方法写下学习笔记 Mixin Mixin编程是一种开发模式,是一种将多个类中的功能单元的进行组合的利用的方式,这听起来就像是 ...

  4. Python之路【第十二篇】:Python面向对象高级

    一.反射 1 什么是反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究 ...

  5. python 面向对象高级编程

    数据封装.继承和多态只是面向对象程序设计中最基础的3个概念.在Python中,面向对象还有很多高级特性,允许我们写出非常强大的功能. 我们会讨论多重继承.定制类.元类等概念.

  6. 17、Python面向对象高级

    一.isinstance和issubclass type():不会认为子类实例是一种父类类型: isinstance():认为子类实例是一种父类类型. issubclass():判断是否为其子类. c ...

  7. Python面向对象高级之类的特殊成员

    上文介绍了Python的类成员以及成员修饰符,从而了解到类中有字段.方法和属性三大类成员,并且成员名前如果有两个下划线,则表示该成员是私有成员,私有成员只能由类内部调用.无论人或事物往往都有不按套路出 ...

  8. python面向对象高级编程

    正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性.先定义class: >>> class Studen ...

  9. python面向对象高级:枚举

    在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数.这两种类型经常(但不总是)重叠. 枚举是一个被命名的整型常数的集合,枚举在日常生活中很常见,例 ...

  10. Python面向对象高级编程-__slots__、定制类,枚举

    当在类体内定义好各种属性后,外部是可以随便添加属性的,Python中类如何限制实例的属性? Python自带了很多定制类,诸如__slots__,__str__ __slots__ __slots__ ...

随机推荐

  1. 关于webform textbox Password 模式

    textbox在这个模式时,如果进行点击按钮或者其他与后台交互的操作,则状态不会保留,既密码框内容会被清空: 这个可以在前台使用 隐藏控件加js获取密码框内容赋值到隐藏控件,点击刷新后通过后台为密码框 ...

  2. MarkDown 编辑器学习

    MarkDown 编辑器学习 是一种简单快键的文字排版工具,可以用于编写说明文档,鉴于其语法简洁明了,且其渲染生成的样式简单美观,很多开发者也用它来写博客,已被国内外很多流行博客平台所支持.生成的文件 ...

  3. C++ Knowledge series overloading

    What does the compiler behind our programming? Overloading in C++ Override all of overloaded functio ...

  4. Form 头行附件查询

    查询Form的头行附件: SELECT  st.short_text order_short_text, description order_attach_desc, pk1_value order_ ...

  5. REP-0118:can not create temporary file(无法创建临时文件)

    解决办法: 查看一下注册表里面的reports_tmp 的路径 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ORACLE\KEY_DevSuiteHome1 .是不 ...

  6. jquery 滑块导航菜单

    带滑块的导航菜单,鼠标悬浮时,滑块会移动至鼠标位置,离开时,滑块会回到原来的位置,点击菜单之后滑块会停留在被点击菜单位置,等待下一次的鼠标悬浮事件或者点击事件,效果图: 图片效果不行,直接上代码: & ...

  7. SharePoint 计时器作业

    本文将介绍 SharePoint 2010 的默认计时器作业,即我们通常说的Timer服务.计时器作业在 SharePoint Server 的特定 Windows 服务中运行.计时器作业还是执行定时 ...

  8. Google面试准备

    本人小弱,面试过了Google的HC,虽然team match还没完成,到最后还有变数.但对自己这段时间的努力,也算一个交代了. 最初是一年半前Google的HR联系到我,然后第一次在电面就挂了.经过 ...

  9. Apache Module mod_ssl

    http://httpd.apache.org/docs/current/mod/mod_ssl.html Description: Strong cryptography using the Sec ...

  10. vue-表单绑定

    表单数据绑定1.1你可以用 v-model 指令在表单控件元素上创建双向数据绑定.它会根据控件类型自动选取正确的方法来更新元素.尽管有些神奇,但 v-model 本质上不过是语法糖,它负责监听用户的输 ...