1. 创建类

类是对某个对象的定义,它包含有关对象动作方式的信息,包括它的名称、方法、属性和事件。类不存在于内存中,因此它本身并不是对象。当程序运行需要引用类的代码时,就会在内存中创建一个类的新实例,即对象。虽然只有一个类,但能以这个类在内存中创建多个相同类型的对象。

class Person(object):#类的方法中必须要有一个self参数,但是方法被调用时,不用传递这个参数def get_name(self):      print "my name is: lili"def get_age(self):print "my age is : 20"def get_hoppy(self):print "My hoppy is :lvyou"boy = Person()
boy.get_name()       #但是方法被调用时,不用传递这个参数
boy.get_age()        #在调用get_age等方法时,boy自动将自己作为一个参数传入方法中,因此我们称它为self
boy.get_hoppy()

使用 PyCharm 进行 Python 开发时,在类中定义方法时,若该方法不涉及对属性的操作,那么PyCharm 会提示 Method xxx may be ‘static’,因为 PyCharm 会认为该方法是一个静态方法,而不是类方法,所提提示我们在该方法前添加 @staticmethod 装饰器进行装饰。

2. 类的封装和多态

所谓封装,即将抽象得到的数据和行为(功能)相结合,形成一个有机整体,也就是将数据和操作数据的源代码进行有机整合,形成类。

其中数据和函数都是类的成员。目的是隐藏对象的属性和实现细节,对外公开接口,在程序中控制属性的读和修改的访问级别。

封装和多态的区别:多态可以让用户对不知道是什么类的对象进行方法调用,而封装则不用关心对象是如何创建的而直接进行使用。

class MyClass(object):# 定义一个全局变量name = 'xml'def set_name(self, name):self.name = namedef get_name(self):return self.namemy = MyClass()
my.set_name('Jack')
print my.get_name()# 如果将变量存储到全局变量name中时,实例化MyClass之后,全局变量name将会改变
my = MyClass()
my.name = 'Tom'
print my.get_name()# 对象有自己的状态,对象的状态由它的特性名称来描述,eg:下面she对象的内容不影响my对象的内容
she = MyClass()
she.set_name('angel')
print she.get_name()
print my.get_name()

3. 类的属性

  • 私有属性

    函数、方法或者属性的名称以两个下划线开始,则为私有类型;

  • 公有属性

    如果函数、方法或者属性的名称没有以两个下划线开始,则为公有属性;

  • 实例属性

    以self作为前缀的属性;

  • 局部变量

    类的方法中定义的变量没有使用self作为前缀声明,则该变量为局部变量;

以单下划线开头(_foo )的代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用 from xxx import 导入;

以双下划线开头的(__foo )代表类的私有成员;

以双下划线开头和结尾的(__ foo__)代表Python里特殊方法专用的标识,如__init()__ 代表类的构造函数。

class Fly():price = 123                      #公有的类属性def __init__(self):self.direction = "beijing"   #公有的实例属性 self.__city = '陕西'          #私有的实例属性isPeople = "more people"     #局部变量if __name__ == '__main__':print Fly.price#print Fly.direction   公有的实例属性在未实例化之前不能使用,该语句是错误的traveller = Fly()print traveller.direction#print traveller.__city    Fly instance has no attribute '__city'print traveller._Fly__city    #私有属性的访问方式:实例化对象名._类名__私有属性名#print traveller.isPeople  局部变量不能被实例化对象traveller所引用Fly.price = traveller.price + 10print "the Fly prise is " + str(Fly.price)mytraveller = Fly()print "I think the price is " + str(mytraveller.price)

数据属性不需要预先定义,数据属性初次被使用时,即被创建并赋值。

class Data_attribute():passif __name__ == "__main__":data = Data_attribute()data.name = "我是没有被预先定义的数据"print data.name
  • 类数据属性属于类本身,可以通过类名进行访问/修改
  • 类数据属性也可以被类的所有实例访问 / 修改
  • 在类定义之后,可以通过类名动态添加类数据属性,新增的类属性也被类和所有实例共有
  • 实例数据属性只能通过实例访问
  • 在实例生成后,还可以动态添加实例数据属性,但是这些实例数据属性只属于该实例
class Student(object):count = 0books = []
'''
"count" "books" "name"和"age"都被称为类的数据属性,但是它们又分为类数据属性和实例数据属性
'''def __init__(self, name, age):      # 类的初始化函数"__init__"self.name = nameself.age = agepass# 1、类数据属性Student.books.extend(['python', 'javascript'])
print 'Student book list: %s' % Student.books
# Student book list: ['python', 'javascript']
# class can add class attribute after class defineStudent.hobbies = ['reading', 'jogging', 'swimming']
print 'Student hobbies list: %s' % Student.hobbies
# Student hobbies list: ['reading', 'jogging', 'swimming']
print dir(Student)
'''
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'books', 'count', 'hobbies']
'''# 2、实例数据属性wilber = Student('wilber', 28)
print '%s is %d years old' % (wilber.name, wilber.age)
# wilber is 28 years old
# class instance can add new attribute
# "gender" is the instance attribute only belongs to wilberwilber.gender = 'male'
print '%s is %s' % (wilber.name, wilber.gender)# class instance can access class attributeprint dir(wilber)
wilber.books.append('C#')
print wilber.bookswill = Student("Will", 27)
print "%s is %d years old" % (will.name, will.age)
# will shares the same class attribute with wilber
# will don't have the "gender" attribute that belongs to wilber
print dir(will)
print will.books

4. 类的方法

  • 类方法

    类方法使用 @classmethod 指令来声明;

  • 类实例方法

    实例方法则无需使用指令来说明;实例方法的第一个参数必须是"self",实例方法只能通过类实例进行调用,这时候"self"就代表这个类实例本身。通过"self"可以直接访问实例的属性

与实例方法和类方法不同,静态方法没有参数限制,既不需要实例参数,也不需要类参数,定义的时候使用 @staticmethod 装饰器。

同类方法一样,静态法可以通过类名访问,也可以通过实例访问。

这三种方法的主要区别在于参数,实例方法被绑定到一个实例,只能通过实例进行调用;但是对于静态方法和类方法,可以通过类名和实例两种方式进行调用。

class MyClass():def __init__(self):passdef aa(self, message):    # 类实例方法print "执行实例方法 aa(%s,%s)" %(self,message)@classmethoddef class_method(cls, message):  # 类方法print "执行类方法 class_method(%s,%s)" %(cls,message)@staticmethoddef static_method():    # 类静态方法print "我是被定义的静态方法"if __name__ == "__main__":qq = MyClass()qq.aa('hello')# My_object.aa('hello')  类实例方法aa只能被类实例调用,不能被类调用# 类方法和静态方法可以直接被类和类实例调用qq.class_method('hello')MyClass.class_method('hello')qq.static_method()MyClass.static_method()

为什么要用到静态方法呢? 如下示例说明:

静态方法用到的场景就是和类相关的操作,但是又不会依赖和改变类、实例的状态,比如经常有跟类有关系的函数,我们希望它在运行时又不需要实例和类参与的情况下直接就能调用。调用静态方法可以无需创建对象。

class Robot(object):def __init__(self, data):self.data = data@staticmethoddef is_need():return Truedef reboot(self):if Robot.is_need():    # 调用类中的静态方法print "The pc will reboot for {0}".format(self.data)def restore(self):if Robot.is_need():print "The pc will restort for {0}".format(self.data)robot1 = Robot("cmd")
robot1.reboot()
robot1.reboot()

类方法的示例

In [15]: class Student(object):...:  num_student=0...:  def __init__(self):...:         Student.num_student+=1...: ...:   @classmethod...:   def get_num_of_instance(cls):...:       return cls.num_student...: In [16]: s1=Student()In [17]: s1.get_num_of_instance()
Out[17]: 1In [18]: s2=Student()In [19]: s2.get_num_of_instance()
Out[19]: 2In [20]: Student.get_num_of_instance()
Out[20]: 2In [21]: s3=Student()In [22]: Student.get_num_of_instance()
Out[22]: 3

简单记录一下 classmethod 和 staticmethod 的区别:

classmethod 是类方法,而 staticmethod 是静态方法。

在 Python中,静态方法和类方法都是可以通过类对象和类对象实例访问。但是区别是:
@classmethod 是一个函数修饰符,它表示接下来的是一个类方法,类方法的第一个参数 cls,而实例方法的第一个参数是 self,表示该类的一个实例。

普通对象方法至少需要一个 self 参数,代表类对象实例,类方法有类变量 cls 传入,从而可以用 cls 做一些相关的处理。并且有子类继承时,调用该类方法时,传入的类变量 cls 是子类,而非父类。

对于类方法,可以通过类来调用,比如说 A 是一个类,那么我们可以通过 A.method() 来调用 A 里面的 method 方法, 也可以通过类的一个实例来调用,如 A().method() 进行调用,首先 A() 方法会调用 A 的初始化方法进行实例化出一个 A 的对象,然后通过该对象调用 method 方法。

静态方法则没有上述方法,它基本上跟一个全局函数相同,一般来说用的很少。

5. 类的继承

继承是指一个对象直接使用另一个对象的属性和方法,当一个类拥有另一个类的所有数据和操作时,就称这两个类之间具有继承关系,被继承的类称为父类或者超类,继承了父类或者超类的所有数据和操作的类称为子类。

继承类语法:

class class_name(fatherclass_name)

fatherclass_name代表的是class_name要继承的类 。

如何调用父类的方法:使用类名访问父类中的方法,并在参数列表中引入对象 self。

class Father():def __init__(self):print '我是初始化Father类中的方法'print '供以后调用'class Son(Father):def __init__(self):print '我是初始化Son类中的方法'Father.__init__(self)   # 使用类名访问父类中的方法,并在参数列表中引入对象selfchild = Son()

下面看一个例子,我们以学校的老师和学生为例,老师和学生有共同的特征:姓名、年龄、地址、喜好,不同的是老师有工资,学生有成绩。

我们将学校成员归为一个共同的类。

class SchoolMember(object):def __init__(self, name, age, addr, hoppy):self.name = nameself.age = ageself.addr = addrself.hoppy = hoppyprint '初始化的名字是%s' %self.namedef tell(self):print '姓名:%s,年龄:%s,地址:%s,喜好:%s'  %(self.name,self.age,self.addr,self.hoppy)

Teacher 类继承 SchoolMember 类,采用新式类继承写法时,super() 会带两个参数,第一个是子类的类名,第二个是 self 参数。super() 可以避免一些类继承的潜在问题,特别是在多重继承上。

class Teacher(SchoolMember):def __init__(self, name, age, addr, hoppy, salary):# 使用类名访问父类中的方法,并在参数列表中引入对象selfSchoolMember.__init__(self, name, age, addr, hoppy)  # 新式类继承写法# super(Teacher, self).__init__(name, age, addr, hoppy)self.salary = salary    # 添加salary属性print '我是继承SchoolMember的老师%s' %(self.name)def tell(self):SchoolMember.tell(self)print '我这次的工资是 %s' %self.salary

Student 类继承 SchoolMember 类

class Student(SchoolMember):def __init__(self, name, age, addr, hoppy, marks):SchoolMember.__init__(self, name, age, addr, hoppy)self.marks = marks      # 添加marks属性print '我是继承SchoolMember的学生%s' %(self.name)def tell(self):SchoolMember.tell(self)print '我这次的成绩是 %s' %self.marks# 分别创建Teacher和Student的实例
t = Teacher('Tom', 40, '陕西西安', '篮球',3000)
s = Student('jack', 14, '北京', '足球', 90)members = (t, s)
for member in members:member.tell()'''
程序输出结果如下:
我是初始化Son类中的方法
我是初始化Father类中的方法
供以后调用
初始化的名字是Tom
我是继承SchoolMember的老师Tom
初始化的名字是jick
我是继承SchoolMember的学生jick
姓名:Tom,年龄:40,地址:陕西西安,喜好:篮球
我这次的工资是 3000
姓名:jack,年龄:14,地址:北京,喜好:足球
我这次的成绩是 90
'''

6. 类的多重继承

子类继承多个父类的方法:

class class_name(fatherclass_name,fatherclass_name1,......):

其中,class_name为类名,fatherclass_name,fatherclass_name1 为父类名。

class MyFather():def __init__(self):self.eye = '爸爸的眼睛是双眼皮'print self.eyeclass MyMother():def __init__(self):self.forehead = '妈妈的额头有点宽'print self.foreheadclass MyAunt():def __init__(self):self.nose = '姑姑的鼻子是高鼻梁'print self.noseclass MySelf(MyFather, MyMother, MyAunt):def __init__(self, face):print '我的眼睛是双眼皮,别人说我是继承的是:'MyFather.__init__(self)print '我的额头有点宽,别人说我是继承的是:'MyMother.__init__(self)print '我的鼻子有点宽,别人说我是继承的是:'MyAunt.__init__(self)self.face = faceprint '我的脸型:%s' %self.face,'这下终于没人说我像谁了'me = MySelf('偏圆吧')

7. 通过对象修改类属性

通过对象可以修改类属性值。但这是危险的。类属性被所有同一类及其子类的对象共享。类属性值的改变会影响所有的对象。

class Human(object):Age = 0Name = ["Li", "Lei"]a = Human()
b = Human()a.Age += 1
print a.Age
print b.Age          # b.Age不会改变    Age是immutable型a.Name[0] = "Wang"
print a.Name
print b.Name        # b.Name会改变     Name是mutable型'''
程序输出结果如下:
1
0
['Wang', 'Lei']
['Wang', 'Lei']
'''

为什么immutable变量是可行的呢?原因是,在更改对象属性时,如果属性是immutable的,该属性会被复制出一个副本,存放在对象的__dict__中。你可以通过下面的方式查看:

print a.__class__.__dict__
print a.__dict__

注意到类中和对象中各有一个Age。一个为0, 一个为1。所以我们在查找a.Age的时候,会先查到对象的__dict__的值,也就是1。
但mutable的类属性,在更改属性值时,并不会有新的副本。所以更改会被所有的对象看到。

8. 类中的方法调用其它方法

class Human(object):laugh = 'hahahahaha'def show_laugh(self):print self.laughdef laugh_10th(self):for i in range(10):self.show_laugh()li_lei = Human()
li_lei.laugh_100th()
#类属性laugh ,在方法show_laugh()中,通过self.laugh,调用了该属性的值。
#还可以用相同的方式调用其它方法。方法show_laugh(),在方法laugh_100th中()被调用

Python 类—类属性(私有属性、公有属性、实例属性、局部变量)类方法(实例方法、静态方法)相关推荐

  1. 类属性,实例属性,私有属性,类方法,实例方法,静态方法,私有方法,魔法方法

    实例对象可以调用实例方法/属性.静态方法.类方法/属性,类对象只能调用静态方法和类方法/属性 dir()函数不带参数时,返回当前范围内的变量.方法和定义的类型列表 dir()函数带参数时会返回该参数的 ...

  2. Python 类的属性与实例属性

    放假归来 ~~~ 一.概念 类对象:类名 实例对象:通过类创建的对象 类属性:类对象所拥有的属性.归类所有,被类对象和实例对象所共有. 类的公有属性可以在类外被访问. 实例属性:实例对象所特有的属性, ...

  3. Python基础——类属性、类方法、异常

    文章目录 一.实例属性和类属性 1.类属性 2.实例属性 3.实例方法 二.实例方法.类方法和静态方法 1.实例方法 2.类方法 3.静态方法 三.__new__方法 三.单例设计模式 四.射击游戏 ...

  4. python类中的属性分为类属性和实例属性两种_python从入门到大神---1、初始化实例、类属性、方法...

    python从入门到大神---1.初始化实例.类属性.方法 一.总结 一句话总结: 方法不加括号是代码段:感觉python方法和js,php很类似,不加括号是代码段,加括号变成方法,比如f,f() 1 ...

  5. python中的类属性、实例属性、类方法、实例方法

    定义类 class Person():pass 创建实例 xiaoming = Person() xiaohong = Person() 实例属性 xiaoming = Person() xiaomi ...

  6. Python 实例属性和类属性

    由于Python是动态语言,根据类创建的实例可以任意绑定属性. 给实例绑定属性的方法是通过实例变量,或者通过self变量: class Student(object):def __init__(sel ...

  7. python中的类属性和实例属性

    类属性和实例属性,一般我们接触到的就是实例属性(对象属性),顾名思义, # 实例属性是对象持有的,不是共享的属性 # 实例属性只有对象能够访问 类属性就是类对象所拥有的属性,它被所有类对象的实例对象所 ...

  8. 初学者python笔记(静态属性、类方法、静态方法、类的组合)

    文章目录 类的三大方法 1.静态属性 2.类方法.静态方法 3.三大方法总结 类的组合 1.用法分析 2.面试案例分析 本篇文章是上一篇:初学者python笔记(面向对象编程.类与对象)的后续篇,是关 ...

  9. python的实例属性_python 实例属性和类属性

    如何在一个类中定义一些常量,每个对象都可以方便访问这些常量而不用重新构造? 第一个问题,在 Python 的类里,你只需要和函数并列地声明并赋值,就可以实现这一点, 例如这段代码中的 WELCOME_ ...

最新文章

  1. 独家 | 麦肯锡教我的数据科学家的五大黄金法则
  2. CCF 2020年题目题解 - Python
  3. Windows Server 2008 R2忘记密码导致无法修改密码
  4. 达内php吾爱_2018年达内c++全套视频课程(不加密)
  5. 架构设计 | 基于Seata中间件,微服务模式下事务管理
  6. raspberry pi_如何购买Raspberry Pi
  7. scala模板写入es_Spark——scala 实用小方法
  8. DT大数据 scala for查询
  9. Android之离线词典
  10. 联想小新锁屏壁纸怎么换_如何设置联想小新电脑锁屏时间
  11. C语言结构体所占用的字节数如何计算
  12. 前段UI框架 layui 和 amazeui 的对比
  13. Specification同时实现模糊查询、排序、分页
  14. Ingress session sticky
  15. html5如何获取音频资源6,【已解决】如何从喜马拉雅的页面中获取到mp3音频文件...
  16. QQ看点内容中心存储系统介绍
  17. Unity适配iphone刘海屏
  18. 痞子衡嵌入式:我被邀请做科锐国际旗下数科同道主办的技术沙龙嘉宾
  19. 一种非Timeline的feeds流架构
  20. BADI的层次分析以及BADI里面的每个块的理解 看完你就懂!

热门文章

  1. 力扣解题——求根到叶子节点数字之和
  2. UUID的使用及其原理
  3. Go 知识点(19)— Go 语言中的野指针
  4. python实现简单的用户密码登录控制(输入三次就锁定用户)
  5. Docker安装Nextcloud
  6. Registry仓库Harbor的部署与简介
  7. LeetCode简单题之最少操作使数组递增
  8. MLIR算子量化Quantization
  9. 人脸照片自动生成游戏角色_ICCV2019论文解析
  10. [C] [编程题]连通块(DFS解决)