Python 面向对象,类的属性和 类的方法

面向对象,类的属性和 类的方法

面向对象

  1. 类和对象
  2. Python类定义
  3. 类属性
  4. 类方法

面向过程和面向对象

面向过程 和 面向对象 编程

  1. 面向过程 编程:函数式编程,C程序,shell等
  2. 面向对象 编程:C++ ,Java,Python

类和对象
类和对象:是面向对象中的两个重要概念
1.类: 是对事物的抽象,比如:人类,球类
2.对象:是类的一个实例,比如:足球,篮球

实例说明:
球类可以对球的特征和行为进行抽象,然后可以实例化一个真实的球实体出来

静态属性,动态方法

为什么面向对象
面向对象的主要思想是:

  1. 封装
  2. 继承
  3. 多态

这种思想方便解决较为复杂的项目,且维护起来较为容易

类的定义

类定义:
类把需要的变量和函数组合成一起,这样包含称为"封装"
class A(object):

类的结构:
class 类名:
成员变量 - 属性
成员函数 - 方法

class MyClass(object):
    def fun(self): print "i am function" 

类的方法中至少有一个参数 self

#!/usr/bin/python

class People(object): # 定义类(class),object可以有,也可以没有 color = 'yellow' #定义了一个静态属性,成员变量 def think(self): #定义了一个动态方法,这个方法里一定要有self,还可以带多个属性,成员函数 self.color = "black" #如果需要调用类里的属性,就要用到self.color来调用该静态属性 print "I am a %s" % self.color #调用动态方法时的输出 print "i am a thinker" ren = People() #将类赋值给'ren'这个变量,就是一个对象,即为将类实例化 print ren # 单纯打印这个'ren'变量是一个对象(object),所以将类实例化后的便是对象(object) print ren.color #输出,'ren'对象的静态属性, ren.think() #使用这个类里面的.think()方法 

输出结果:

[root@hc python]# python class.py 
<__main__.People object at 0x7f646d144690>    #打印这个方法的信息

yellow           #静态属性的输出结果 I am a black #这里输出的是 ren.think() i am a thinker 

对象的创建

创建对象的过程称之为实例化;
当一个对象被创建后,包含三个方面的特性

  1. 对象句柄
  2. 属性
  3. 方法

句柄用于 区分不同的对象
对象的属性和方法与类中的成员变量和成员函数对应

obj = MyClass() # 创建类的一个实例(对象)通过对象来调用方法和属性

类的属性

类的属性按使用范围分为公有属性和私有属性,类的属性范围取决于属性的名称

公有属性:
在类中和类外都能调用的属性

私有属性:
不能再类外以及被类以外的函数调用

定义方式:
以"__"双下划线开始的成员变量就是私有属性
可以通过instance._classname__attribute方式访问

内置属性:由系统在定义类的时候默认添加的,由前后双下划线构成,__dict__ , __module__

#!/usr/bin/python
#coding:utf8
class People(object): color = 'yellow' __age = 30 #前面加两个__ 为私有属性,只能内部使用 def think(self): self.color = "black" print "I am a %s" % self.color print "i am a thinker" print self.__age #调用私有属性 ren = People() #将类实体化 ren.color = 'aaa' #对象内的color属性重新赋值 print ren.color #输出这个对象被新赋值的属性 print People.color() #调用类里的属性,是原来的值,是因为类实体化之前之后是不同的个体 print '-' *50 ren.think() #调用对象里的方法 print '-' *50 print ren.__dict__ #通过对象调用公有的属性,保存到字典里输出 print People.__dict__ #通过类调用内置属性,公私有属性全部保存到字典输出 print '-' *50 print ren._People__age #以这种方法查看对象里的私有属性,测试用 

输出结果:

[root@hc python]# python class1.py 

#  ren = People()      
#  ren.color = 'aaa'   
#  print ren.color   
# print People.color() aaa yellow -------------------------------------------------- # ren.think() I am a black i am a thinker 30 #这是私有属性 -------------------------------------------------- # print ren.__dict__ {'color': 'black'} # print People.__dict__ {'__module__': '__main__', 'color': 'yellow', '__doc__': None, '__dict__': <attribute '__dict__' of 'People' objects>, '_People__age': 30, '__weakref__': <attribute '__weakref__' of 'People' objects>, 'think': <function think at 0x7fe443e265f0>} -------------------------------------------------- # print ren._People__age 30 

类的方法

  1. 方法的定义和函数一样,但是需要self 作为第一个参数
  2. 类方法:
    公有方法
    私有方法
    类方法
    静态方法

公有方法:在类中和类外都能调用的方法

私有方法:不能被类的外部调用,在方法前面加上"__"双下划线就是私有方法

self 参数
用于区分函数和类的方法(必须有一个self),self参数表示执行对象本身

方法和函数的区别是:在括号内有没有self,有self就是方法,没有就是函数

self代表类的本事

通过类调用!
类的方法 (能被类直接调用的叫做类方法)
类方法:
classmethod()函数处理过的函数,能被类所调用,也能被对象所调用(是继承的关系)

classmethod
修饰符对应的函数不需要实例化,不需要 self 参数,但第一个参数需要是表示自身类的 cls 参数,可以来调用类的属性,类的方法,实例化对象等。

静态方法:
相当于"全局函数",可以被类直接调 用,可以被所有实例化对象共享,通过staticmethod()定义,
静态方法没有self参数。

装饰器:

@classmethod    
# 指定一个类的方法为类方法,通过这个函数classmethod,(单独写需要一个变量来接受值)
#动态方法占用资源比较少,用到了才会加载,但是访问速度比较慢


@staticmethod  
#只针对它下面的函数生效,它是将函数转为类的静态方法,静态方法比较占用资源,但是访问速度快 #静态方法无需实例化,但也可以也可以实例化后调用 

使用例子

#!/usr/bin/python
#coding:utf8
class People(object): color = 'yellow' __age = 30 def think(self): self.color = "black" print "I am a %s" % self.color print "i am a thinker" print self.__age def __aaa(self): # 私有方法,只能内部调用 print "使用私有方法 " def axx(self): #需要使用到一个类的方法内部调用才可以访问到内部的私有方法 self.__aaa()  @classmethod #类方法 def test(x): #修饰符对应的函数不需要实例化,不需要self参数,但第一个参数需要是表示自身类的x参数,可以来调用类的属性,类的方法,实例化对象等。 print x.color print "动态方法"  @staticmethod #静态方法无需实例化,但也可以也可以实例化后调用 def test1(): print "静态方法" print "通过实体化后的类访问" abc = People() abc.test() abc.test1() print "---------------------" print "通过类访问的" People.test() People.test1() print "---------------------" abc.axx()

类的内置方法  和 继承

python 内部类

所谓内部类,就是再类的内部定义的类,主要目的是为了更好的抽象实现世界
例子:
汽车是个类,汽车的底盘,轮胎也可以抽象为类,将其定义到汽车类中,则形成内部类,更好的描述汽车类,因为底盘,轮胎是汽车的一部分

内部类的实例化方法
方法1:直接使用外部类调用内部类
object_name = outclass_name.inclass_name()

方法2:先对外部类进行实例化,然后再实例化内部类

out_name = outclass_name()
in_name = out_name.inclass_name()
in_name,method()

方法3:公有属性,直接可以通过类直接调用

魔术方法

类的内置方法或者叫做魔术方法

__str__(self)
将输出对象更友好的输出

构造函数与析构函数
构造函数:
用于初始化类的内部状态,Python提供的构造函数是__init__();
__init__()方法是可选的,如果不提供,Python会给出一个默认的__init__方法

析构函数:
用于释放对象占用的资源,Python提供的析构函数是 __del__();
__del__()也是可选的。如果不提供,则Python 会在后台提供默认析构函数

垃圾回收机制

1.Python 采用垃圾回收机制来清理不再使用的对象;Python提供gc模块释放不再使用的对象。

2.Python采用"引用计数"的算法方式来处理回收
即:当某个对象在其作用域内不再被其他对象引用的时候,Python就自动清除对象;

3.gc模块的collect()可以一次性收集所有待处理的对象 print gc.collect()如果是0则为回收

类的继承

  1. 继承是面向对象的重要特性之一;
  2. 继承关系:继承是相对两个雷而言的父子关系,子类继承了父类的所有公有属性和方法
  3. 继承实现了代码重用

使用继承
继承可以重用已经存在的数据和行为,减少代码的重复编写,Python在类名后使用一对括号来表示继承关系,括号中的类即为父类。

class Myclass(ParentClass) class Myclass继承了ParentClass类

如果父类定义了__init__方法,子类必须显示调用父类的__init__方法:
ParentClass.__init__(self,[args...])

如果子类需要扩展父类的行为,可以添加__init__方法的参数

简单的继承:

#!/usr/bin/python
#-*- coding:utf-8 -*-

class People(object): #New Style 传统方式不加() color = 'yellow' def __init__(self, c): #父类的构造函数,如果self后跟了一个变量,则在继承的子类时需要重写这个构造函数然后引入这个值 print "Init..." self.dwell = 'Earth' #这是它的初始化变量 def think(self): print "I am a %s" % self.color print "I am a thinker " class Chinese(People): #Chinese继承了People父类 def __init__(self): #则在继承的子类时需要重写这个构造函数然后引入这个值 #People.__init__(self,'red') #第一种方法可以使用传统的方式 ,super 是第二种方法,不支持传统格式的类 super(Chinese, self).__init__('red') #使用super函数来继承父类,父类必须是NewStyle,不然会报错 pass cn = Chinese() #实例化调用这个类 print cn.color #输出里面定义的变量 cn.think() #还能通过继承的类,访问它内部的函数 print cn.dwell #也是会执行内部初始化的变量 

super 函数 来继承父类

class Chinese(People):
Chinese继承了People父类

`def __init__(self):   `   

则在继承的子类时需要重写这个构造函数然后引入这个值
super(Chinese, self).__init__('red') #使用super函数来继承父类,
pass

Help on class super in module __builtin__: class super(object) | super(type, obj) -> bound super object; requires isinstance(obj, type) | super(type) -> unbound super object | super(type, type2) -> bound super object; requires issubclass(type2, type) | Typical use to call a cooperative superclass method: | class C(B): | def meth(self, arg): | super(C, self).meth(arg) 

People.__init__(self,'red')
第一种方法可以使用传统的方式 ,super 是第二种方法,不支持传统格式的类

super(Chinese, self).__init__('red')
使用super函数来继承父类,父类必须是NewStyle,不然会报错

继承2

多重继承
Python 支持多重继承,即一个类可以继承多个父类
语法
class class_name(Parent_c1,Parent_c2,...)

注意:
当父类中出现多个自定义的__init__方法时,
多重继承只执行第一个类的__init__方法
其他不执行

类属性,方法 总结

类的属性-总结

  1. 类属性,也是共有属性

  2. 类的私有属性

  3. 对象的共有属性

  4. 对象的私有属性

  5. 内置函数

  6. 函数的局部变量

  7. 全局变量

#!/usr/bin/python
#coding:utf8

var5 = '全局变量'
class MyClass(object): var1 = '类属性,类的公有属性 var1' __var2 = '类的私有属性 __var2' def func1(self): self.var3 = '对象的公有属性 var3' self.__var4 = '对象的私有属性 __var4' var5 = '函数的局部变量 var5' print self.__var4 print var5 def func2(self): print self.var1 print self.__var2 print self.var3 #需要先调用方法,才能被调用 print self.__var4 print var5 #全局变量! return '这是函数的返回值,没有return就会出现None' mc = MyClass() mc.func1() print '---------' print mc.func2() print '---------' --------------------------------------------- mc = MyClass() #实例化类 print mc.var1 #私有属性都不能访问 mc.func1() #先调用方法 才能调用内部的公有属性 print mc.func1() mc1 = MyClass() print mc1.var3 #没调用内部的方法,所以不能调用 ---------------------------------------------- #通过类 ,对象的属性只能通过对象访问, print MyClass.var1 #访问类的公有属性 可以 print MyClass.var2 #访问类的私有属性 不可以 mc = MyClass() mc.fun1 mc.fun2 print '-' * 50 print mc.__dict__ #返回一个字典,里面包含的是'类的内置属性' print '-' * 50 print MyClass.__dict__ #通过类来调用'内置属性',返回一个字典,里面包含的类来调用'内置属性' 

类方法总结

  1. 公有方法

  2. 私有方法

  3. 类方法

  4. 静态方法

  5. 内置方法

#!/usr/bin/python 
#coding:utf8

class MyClass(object): name = 'Test' def __init__(self): #如果加了内部的构造函数,即当前的类别实例化会, self.func1() #会自动加载,并初始化里面的内容 self.__func2() self.classFun() #类方法,静态方法 这两种都可以通过对象来调用 self.staticFun() def func1(self): print self.name, print "我是公有方法" # self.__func2() def __func2(self): print self.name, print "我是私有方法" @classmethod #修饰器,这样就将类里的方法,转为类方法然后外部调用 def classFun(self): print self.name, print "我是类方法" @staticmethod #修饰器 def staticFun(): #静态方法不能有 self 方法 print MyClass.name, #因为是静态的,需要类名来调用 print "我是静态方法" mc = MyClass() #实例化 mc.func1() mc.__fun2() #直接调用不行。必须在内部调用,在func1里面调用才可以 ------------------------------------------------------------------------------------ MyClass.classFun() #类方法,需要加修饰器才可以再外部调用 MyClass.staticFun() #静态方法,需要加修饰器才可以再外部调用 #类方法,静态方法 这两种都可以通过对象来调用 

rc脚本(类的定义与脚本的结构)

#!/usr/bin/python
import sys
import os
from subprocess import Popen, PIPE #调用系统bash 启动,stdout的标准输出通过这个PIPE管道符传入一个临时文件里 class Process(object): '''memcached rc script''' #注释 def __init__(self, name, program, args, workdir): #类实例化的时候,初始化传递的参数 self.name = name self.program = program #初始化属性 self.args = args self.workdir = workdir def _init(self): #这里是一个下划线,是一个普通的方法 '''/var/tmp/memcached''' if not os.path.exists(self.workdir): # 判断目标不存在,则创建,进入该目录 os.mkdir(self.workdir) # mkdir 创建目录 os.chdir(self.workdir) # chdir 进入该目录 def _pidFile(self): '''/var/tmp/memcached/memcached.pid''' return os.path.join(self.workdir, "%s.pid" % self.name) #将目录连接到一起,然后返回这个结果 def _writhPid(self): if selp.pid: #判断这个pid 是否有值,有值则写入文件 with open(self._pidFile(),'w') as fd: fd.write(str(self.pid)) def start(self): #类里的方法 self._init() #这个方法判断这个目录在不在,不在就创建。 cmd = self.program + ' ' + self.args #启动脚本的路径 + ' ' + 启动选项参数 p = Popen(cmd, stdout=PIPE, shell=True) # 这条是执行命令,stdout=PIPE:是将标准输出传给管道,传给一个临时文件里 self.pid = p.pid #用了Popen里的一个pid方法输出PID self._wirthPid() #调用方法写PID 这个值 print "%s start Sucessful" % self.name def _getPid(self): p = Popen(['pidof',self.name],stdout=PEPI) pid = p.stdout.read().strip() # strip() 去除收尾的空格,换行等。可以执行去掉的字符,需要在括号内写 return pid def stop(self): self._getPid() if pid: #判断这个不为空则执行 os.kill(int(pid),15) #调用系统命令 kill 进程,用kill -15 相当正常退出,kill()里面需要两个参数,一个是PID和等级 if os.path.exists(self._pidFile()): os.remove(self._pifFile()) print " %s is stop" % self.name def restart(self): self.stop() self.start() def status(self): pid = self._getPid() if pid: print "%s is runing" % self.name elif pid: print "%s in stopped" % self.name def help(self): print "Usage: %s {start|stop|status|restart}" % __file__ # __file__ 打印这个内置属性,则是该文件名 def main(): #一个主体函数 name = 'memcached' #程序名 prog = '/usr/bin/memcached' #程序的启动脚本的路径 args = '-u nobody -p 11211 -c 1024 -m 64' #启动时带的参数 wd = '/var/tmp/memcached' #程序所在的路径 pm = Process(name = name, #上面的参数 传入类的属性里去 program = prog, args = args, workdir = wd) try: #处理输入的异常 cmd = sys.argv[1] #取输入脚本的第一个值 比如,start,stop等等。。 except IndexError, e: #except 异常的捕捉 print "Option error" sys.exit() if cmd == 'start': #判断输入的类型 pm.start() # 实例化后的类 进行调用内部的方法 elif cmd == 'stop': pm.stop() elif cmd == 'restart': pm.restart() elif cmd == 'status': pm.status() else: pm.help() if __name__ == '__main__': #调用使用 main() 函数,print(__name__) 打印的输出就等于__main__ main() #这里等同于启动python程序的意思 

Linux kill 命令

9和15 的区别,最好还是用15,这样相当于正常退出
SIGNKILL(9) 的效果是立即杀死进程. 该信号不能被阻塞, 处理和忽略。
SIGNTERM(15) 的效果是正常退出进程,退出前可以被阻塞或回调处理。并且它是Linux缺省的程序中断信号。

linux 命令

echo $$ #当前PID的bash 进程
tty #显示当前终端号
pidof #取一个进程的PID

关于 get pid 的问题

from subprocess import Popen, PIPE #先加载模块

p = Popen(['pidof','memcached'], stdout=PIPE) #将Popen 实例化 给p

p.pid #p调用pid方法 ,这个PID 是 pidof命令的进程的PID
28675

pid = p.stdout.read() #这个PID才是我memcached的进程PID

pid
'28001\n'

pid.strip() #用strip() 字符串方法 去掉 特殊字符
'28001'

猜你喜欢

转载自www.cnblogs.com/huidou/p/10761048.html