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 '

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

原文地址:https://www.cnblogs.com/huidou/p/10761048.html