Python 类—类属性(私有属性、公有属性、实例属性、局部变量)类方法(实例方法、静态方法)
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 类—类属性(私有属性、公有属性、实例属性、局部变量)类方法(实例方法、静态方法)相关推荐
- 类属性,实例属性,私有属性,类方法,实例方法,静态方法,私有方法,魔法方法
实例对象可以调用实例方法/属性.静态方法.类方法/属性,类对象只能调用静态方法和类方法/属性 dir()函数不带参数时,返回当前范围内的变量.方法和定义的类型列表 dir()函数带参数时会返回该参数的 ...
- Python 类的属性与实例属性
放假归来 ~~~ 一.概念 类对象:类名 实例对象:通过类创建的对象 类属性:类对象所拥有的属性.归类所有,被类对象和实例对象所共有. 类的公有属性可以在类外被访问. 实例属性:实例对象所特有的属性, ...
- Python基础——类属性、类方法、异常
文章目录 一.实例属性和类属性 1.类属性 2.实例属性 3.实例方法 二.实例方法.类方法和静态方法 1.实例方法 2.类方法 3.静态方法 三.__new__方法 三.单例设计模式 四.射击游戏 ...
- python类中的属性分为类属性和实例属性两种_python从入门到大神---1、初始化实例、类属性、方法...
python从入门到大神---1.初始化实例.类属性.方法 一.总结 一句话总结: 方法不加括号是代码段:感觉python方法和js,php很类似,不加括号是代码段,加括号变成方法,比如f,f() 1 ...
- python中的类属性、实例属性、类方法、实例方法
定义类 class Person():pass 创建实例 xiaoming = Person() xiaohong = Person() 实例属性 xiaoming = Person() xiaomi ...
- Python 实例属性和类属性
由于Python是动态语言,根据类创建的实例可以任意绑定属性. 给实例绑定属性的方法是通过实例变量,或者通过self变量: class Student(object):def __init__(sel ...
- python中的类属性和实例属性
类属性和实例属性,一般我们接触到的就是实例属性(对象属性),顾名思义, # 实例属性是对象持有的,不是共享的属性 # 实例属性只有对象能够访问 类属性就是类对象所拥有的属性,它被所有类对象的实例对象所 ...
- 初学者python笔记(静态属性、类方法、静态方法、类的组合)
文章目录 类的三大方法 1.静态属性 2.类方法.静态方法 3.三大方法总结 类的组合 1.用法分析 2.面试案例分析 本篇文章是上一篇:初学者python笔记(面向对象编程.类与对象)的后续篇,是关 ...
- python的实例属性_python 实例属性和类属性
如何在一个类中定义一些常量,每个对象都可以方便访问这些常量而不用重新构造? 第一个问题,在 Python 的类里,你只需要和函数并列地声明并赋值,就可以实现这一点, 例如这段代码中的 WELCOME_ ...
最新文章
- 独家 | 麦肯锡教我的数据科学家的五大黄金法则
- CCF 2020年题目题解 - Python
- Windows Server 2008 R2忘记密码导致无法修改密码
- 达内php吾爱_2018年达内c++全套视频课程(不加密)
- 架构设计 | 基于Seata中间件,微服务模式下事务管理
- raspberry pi_如何购买Raspberry Pi
- scala模板写入es_Spark——scala 实用小方法
- DT大数据 scala for查询
- Android之离线词典
- 联想小新锁屏壁纸怎么换_如何设置联想小新电脑锁屏时间
- C语言结构体所占用的字节数如何计算
- 前段UI框架 layui 和 amazeui 的对比
- Specification同时实现模糊查询、排序、分页
- Ingress session sticky
- html5如何获取音频资源6,【已解决】如何从喜马拉雅的页面中获取到mp3音频文件...
- QQ看点内容中心存储系统介绍
- Unity适配iphone刘海屏
- 痞子衡嵌入式:我被邀请做科锐国际旗下数科同道主办的技术沙龙嘉宾
- 一种非Timeline的feeds流架构
- BADI的层次分析以及BADI里面的每个块的理解 看完你就懂!