四、面向对象进阶

1、类方法

普通的方法通过对象调用,至少有一个self参数(调用的时候系统自动传递,不需要手工传递),而类方法由类直接调用,至少有一个cls参数,执行时,自动将调用该方法的类赋值个cls

1
2
3
4
5
6
7
8
class Foo(object):
    def __init__(self):
        pass
    @classmethod # 类方法装饰器,通过他把一个方法装饰成类方法
    def class_func(cls): # cls参数就是这个类本身,注意与self不同,self表示类的对象本身
        print('class_func', cls)
if __name__ == '__main__':
    Foo.class_func()

2、静态方法

由类调用,没有默认参数

1
2
3
4
5
6
7
8
class Foo(object):
    def __init__(self):
        pass
    @staticmethod # 静态方法装饰器,通过他把一个方法装饰成静态方法
    def static_func(): # 与类方法不同的是没有默认参数cls
        print('static_func')
if __name__ == '__main__':
    Foo.class_func()

3、属性

由对象调用,除了self不能有其他参数,调用的时候不用(),看上去就像变量一样,但其实本质还是一个方法,可以通过return把一串执行过程的返回结果返回,从外面看就像是一个只读的变量

1
2
3
4
5
6
7
8
9
class Foo(object):
    def __init__(self, count):
        self.__count = count
    @property # 属性装饰器,通过他把一个方法装饰成属性
    def count(self):
        return self.__count
if __name__ == '__main__':
    obj = Foo(1)
    print(obj.count) # 从外面调用的时候不用()看上去就像一个变量

属性的主要功能就是将内部复杂的逻辑计算得出的记过返回,所以建议最好有返回值,并且内部不要有print()否则虽然语法上不报错,并且的确没有啥问题,但失去了存在的意义。

到目前为止属性和变量相比还只是只读的,我们可以通过@属性名.setter装饰器定义一个修改属性的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Foo(object):
    def __init__(self, count):
        self.__count = count
    @property # 属性装饰器,通过他把一个方法装饰成属性
    def count(self):
        return self.__count
    @count.setter
    def count(self, value): # 这里除了self只能有一个参数
        self.__count = value
if __name__ == '__main__':
    obj = Foo(1)
    print(obj.count)
    obj.count = 2 # 解释器会自动把赋值号后面的值作为参数传递给方法
    print(obj.count)

另外变量还可通过del关键字进行销毁,属性同样可以

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Foo(object):
    def __init__(self, count):
        self.__count = count
    @property # 属性装饰器,通过他把一个方法装饰成属性
    def count(self):
        return self.__count
    @count.setter
    def count(self, value): # 这里除了self只能有一个参数
        self.__count = value
    @count.deleter
    def count(self): # 这里除了self不能有其他参数
        del self.__count
 
if __name__ == '__main__':
    obj = Foo(1)
    del obj.count # 解释遇到del关键字自动调用对应的deleter方法

到此,一个属性和变量的最大区别就只剩下变量就是一个变量而属性可以内部执行一大堆逻辑

4、成员修饰符__

通过两个下划线“__”,修饰的都是私有,仅仅只是内部进行调用,并且不能继承(要特别注意,有中很贴切的说法形容私有,父亲的钱、房子儿子是共有的可以继承,父亲的女人是私有的,不可以继承),包裹类变量,实例变量,方法等都可以使用__修饰变成私有的

1
2
3
4
5
6
class Foo(object):
    __name = 'name' # 私有类变量
    def __init__(self):
        self.__age # 私有成员变量
    def __funce(self): # 私有方法
        pass

5、特殊成员

有一些成员不需要定义,解释器会自动加载,可以理解为这些都是继承自object

__init__:

构造方法,这里就不多说了,通过类创建对象时,自动触发执行

__doc__:

表示类的描述信息

1
2
3
4
5
6
7
8
9
class Foo(object):
    '''
    类的描述信息
    '''
    def __init__(self):
        pass
 
if __name__ == '__main__':
    print(Foo.__doc__)

输出结果

1
类的描述信息

__module__和__class__

__module__ 表示这个或对象属于哪个模块

__class__ 表示对象属于哪个类

1
2
3
4
5
6
7
8
9
10
11
class Foo(object):
    '''
    类的描述信息
    '''
    def __init__(self):
        pass
 
if __name__ == '__main__':
    print(Foo.__module__)
    obj = Foo()
    print(obj.__class__)

输出结果

1
2
__main__
<class '__main__.Foo'>

__del__

析构方法,当对象在内存中销毁的时候自动触发执行

1
2
3
4
5
6
class Foo(object):
    def __del__(self):
        print('del object')
 
if __name__ == '__main__':
    obj = Foo()

执行结果

1
del object

说明:Python解释器有自己的内存回收机制,这里当程序执行完了的是否触发析构方法,也可以使用del关键字手动销毁对象触发

__call__

在Python中,对象后面加括号,就会触发这个方法,如果没有这个方法就不可以。

1
2
3
4
5
6
7
class Foo(object):
    def __call__(self):
        print('__call__ is exec')
 
if __name__ == '__main__':
    obj = Foo()
    obj()

执行结果

1
__call__ is exec

__dict__

类或者对象中的所有成员

1
2
3
4
5
6
7
8
9
10
11
12
13
class Province(object):
    country = 'China'
 
    def __init__(self, name):
        self.name = name
 
    def func(self):
        pass
 
if __name__ == '__main__':
    print('Class dict:', Province.__dict__)
    obj = Province('zhangsan')
    print('Object dict:', obj.__dict__)

输出结果

1
2
Class dict: {'__weakref__': <attribute '__weakref__' of 'Province' objects>, '__module__': '__main__', 'func': <function Province.func at 0x0000023BD2288950>, 'country': 'China', '__init__': <function Province.__init__ at 0x0000023BD22888C8>, '__dict__': <attribute '__dict__' of 'Province' objects>, '__doc__': None}
Object dict: {'name': 'zhangsan'}

说明:可以看出只有name是属于对象的,其他的都是属于类的,也就是说所有的方法都是属于类而不属于对象,当执行对象名.方法名()调用方法的时候,Python解释器会自动将对象本身作为方法的第一个参数传递给方法,也就是方法里self参数。

__str__

如果类中定义了一个__str__方法,当我们打印这个类的实例的时候回调用这个方法的返回值,所以这个方法必须有return,否则就会报错(TypeError: __str__ returned non-string (type NoneType))

1
2
3
4
5
6
7
8
class Foo(object):
    def __str__(self):
        return 'Foo object'
 
#class Foo()
if __name__ == '__main__':
    obj = Foo()
    print(obj)

输出结果

1
Foo object

我的Python成长之路---第七天---Python基础(21)---2016年2月27日(晴)的更多相关文章

  1. 我的Python成长之路---第七天---Python基础(22)---2016年2月27日(晴)

    socket网络编程 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ...

  2. 我的Python成长之路---第四天---Python基础(16)---2016年1月23日(寒风刺骨)

    四.正则表达式     字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在.比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和 ...

  3. 我的Python成长之路---第四天---Python基础(15)---2016年1月23日(寒风刺骨)

    二.装饰器     所谓装饰器decorator仅仅是一种语法糖, 可作用的对象可以是函数也可以是类, 装饰器本身是一个函数, 其主要工作方式就是将被装饰的类或者函数当作参数传递给装饰器函数.本质上, ...

  4. 我的Python成长之路---第四天---Python基础(14)---2016年1月23日(寒风刺骨)

    一.生成器和迭代器 1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退. ...

  5. 我的Python成长之路---第三天---Python基础(12)---2016年1月16日(雾霾)

    四.函数 日常生活中,要完成一件复杂的功能,我们总是习惯把“大功能”分解为多个“小功能”以实现.在编程的世界里,“功能”可称呼为“函数”,因此“函数”其实就是一段实现了某种功能的代码,并且可以供其它代 ...

  6. 我的Python成长之路---第三天---Python基础(13)---2016年1月16日(雾霾)

    五.Python的常用的内置函数 Python为我们准备了大量的内置函数,如下图所示 这里我们只讨论红框内的内置函数 abs(x) 返回一个数的绝对值(模),参数可以是真说或浮点数 >>& ...

  7. 我的Python成长之路---第三天---Python基础(11)---2016年1月16日(雾霾)

    三.深浅拷贝 在Python中将一个变量的值传递给另外一个变量通常有三种:赋值.浅拷贝以及深拷贝 讨论深浅拷贝之前我们把Python的数据类型分为基本数据类型包括数字.字符串.布尔以及None等,还有 ...

  8. 我的Python成长之路---第三天---Python基础(10)---2016年1月16日(雾霾)

    二.collections collections是对Python现有的数据类型的补充,在使用collections中的对象要先导入import collections模块 1.Counter——计数 ...

  9. Python高手之路【七】python基础之模块

    本节大纲 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configparse ...

随机推荐

  1. 男装电子零售商East Dane即将面世_衣装_YOKA时尚网

    男装电子零售商East Dane即将面世_衣装_YOKA时尚网 男装电子零售商East Dane即将面世

  2. 四核网络机顶盒芯片局势分析(开放市场):rk3128将会成为四核主流

    开放市场:不包含小米.乐视等大品牌闭环生态系统的市场. 今年四核网络播放器以全志的a31s独领风骚.英菲克以绝对优势率先各大白牌品牌公司.只是随着时间的推移,全志的a31s不适应市场主流.因为芯片没有 ...

  3. #pragma的用法

    在所有的预处理指令中,#Pragma   指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和 C++语言完全 ...

  4. js页面loading加载

    <html>     <head>     <title>页面正在载入</title>       <script  language=" ...

  5. 一些ASP.NET的小知识点

    DataFormatString="{0:格式字符串}" 我们知道在DataFormatString 中的 {0}表示数据本身,而在冒号后面的格式字符串代表所们希望数据显示的格式; ...

  6. Foundation 框架 NSString常用总结

    iOS开发过程中,从始至终都会和NSString打交道,在此总结一下NSString的常用的方法,在以后的学习过程中用到的方法也会继续添加 NSString类是Foundation框架中得不可变字符串 ...

  7. php开发中的一些常用统计的日期

    <?php echo '<br>今天:<br>'; echo date("Y-m-d",strtotime("now")), &q ...

  8. php如何开启GD库

    GD库是干什么用的呢!它是php处理图形的扩展库,GD库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片.GD库在php中默认是没有开启的,如果想让它支持图片处理功能,那么就要手 ...

  9. A Byte of Python 笔记(5)函数:定义、形参、局部变量、默认参数、关键参数

    第7章  函数 函数是重要的程序段.它们允许你给一块语句一个名称,然后你可以在程序的任何地方使用这个名称任意多次地运行这个语句块.这被称为 调用 函数. 定义函数 函数通过 def 关键字定义.def ...

  10. Dokcer 组成原理简介

    首先来张图了解Docker的组成 重要 Docker在启动容器的时候,需要创建文件系统,为rootfs提供挂载点.最初Docker仅能在支持Aufs文件系统的Linux发行版上运行,但是由于Aufs未 ...