浅谈 python的类和对象

浅谈 python的类

 刚结束了python的方法,开始看类的时候有点迷糊,类的属性和方法,对象的属性和方法,构造函数,传参。下面就一点点来 分析下。
 
类(Class) 官方给出的解释是 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
    这里表示 类里可以有多个属性,也可以有多个方法。同时也有自己的字段。
    这里的属性 官方语言叫做 类变量,属于这个类的公用部分,谁都可以来用,所以通常不作为实例变量使用,就是一个符号。而方法,则是在类中
    定义的函数,可以理解为类的行为部分。
    

下面展示了类的成员:      

                                           普通字段
                                字段:
                                            静态字段
                                                普通方法
                类成员:方法:    类方法
                                                静态方法
                                属性: 普通属性
                        
                        
        字段: 普通字段属于对象,静态字段属于类,如
            class Province:
                # 静态字段
                country = '中国'
                def __init__(self, name):
                    # 普通字段        普通字段在每个对象中都要保存一份
                    self.name = name
            # 直接访问普通字段
            obj = Province('河北省')
            print obj.name
            # 直接访问静态字段        静态字段在内存中只保存一份
            Province.country
                
        方法:    
                class Foo:
                    def __init__(self, name):
                        self.name = name
                    def __init__(self):
                        pass
                    def ord_func(self):
                        """ 定义普通方法,至少有一个self参数 """
                        # print self.name
                        print('普通方法')
                    @classmethod  #表示下面的方法是类方法  将类本身作为对象进行操作的方法
                    def class_func(cls):
                        """ 定义类方法,至少有一个cls参数 """
                        print('类方法')
                    @staticmethod   #标明这是一个静态方法
                    def static_func():
                        """ 定义静态方法 ,无默认参数"""
                        print('静态方法')
                # 调用普通方法
                f = Foo()
                f.ord_func()
                # 调用类方法
                Foo.class_func()
                # 调用静态方法
                Foo.static_func()
        
        属性:
                class Foo:
                    def func(self):
                        pass
                    # 定义属性
                    @property
                    def prop(self):
                        pass
                # ############### 调用 ###############
                foo_obj = Foo()
                foo_obj.func()
                foo_obj.prop   #调用属性
                
                注意:
                    定义时,在普通方法的基础上添加 @property 装饰器;
                    定义时,属性仅有一个self参数
                    调用时,无需括号
                               方法:foo_obj.func()
                               属性:foo_obj.prop

                注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象

                        属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。
                            
实例化:通过类创建出一个对象,叫做实例化一个类。这里创建出的对象,官方语言是:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。、

这样  才有了类 和对象 两个概念,类 一般不生成实例变量,当然你可以当做默认值来给他赋值。
比如 A = AA()  AA.name  在A中也可以使用,A.name = AA.name 的默认值,如果你赋予了 A.name 值以后,等同于 A.name  覆盖了AA.name 的值,如果不想要A.name 的值,那么直接 del A.name
然后再打印 A.name  你会发现 A.name  就是 AA.name 的默认值了,当然,一般情况下不建议把  AA.name 作为实例变量使用,仅仅是类成员。
就是说 --------   如果增加了类属性,实例属性一定会增加,但是增加了实例属性,类属性不受影响

好吧,接下来就是 类中的成员变量的访问入口,注意,类中创建了成员变量 比如上面的 AA.name  在 AA这个类的方法内是无法直接访问的,这点和java不同,python 需要一个领路人(self)
通过 self.name 才可以在类的方法内访问这个属性的值。

最需要注意的一点:
如果在类初始化中创建一个变量(或者类初始化的变量)  该变量在类中任何一个方法中被重新修改,那么无论是其他方法调用还是被实例化的
对象调用,这个变量的值都会随着改变而改变 下面我们看下他们的name是否改变,结果证实  name 也会随着变化的。    
    ***之所以不推荐创建类的属性值 是因为这个是可变的,并且任何一处定义了都能改变值,维护非常困难,一般建议通过self 来传值

如:
import datetime as time

class Alarm(object):
     alarm_name='不在位指示'
     alarm_id=0
     alarm_start=time.datetime.now().strftime('%Y-%m-%d %H:%M:%S')

     def getAlarmByID(self):
         print('根据 告警ID 获取告警:',self.alarm_id)
         return "123"

     def testAlarm(self):
         print('测试告警信息 alarm_name = ',self.alarm_name,'  alarm_id= ',self.alarm_id,'  alarm_start=',self.alarm_start)
     def test2(self):
         print("测试 str 参数 = ",str,'  alarm_name= ',self.alarm_name)
         self.alarm_name='AIS'
         return self.alarm_name
     def test3(self):
         print(self.alarm_name)

aa = Alarm()
aa.alarm_name = 'R_LOS'  #这里开始修改 alarm_name 的值
aa.test2()            #这里 R_LOS 会取代 不在位指示  同时在方法 test2 中再次修改 alarm_name 的值
print(aa.alarm_name)  这里最终的值是test2 中修改的 AIS
aa.test3()                #不管是 test3里的打印 还是 aa.alarm_name 的打印,都是 test2 最后修改的那个值 即  AIS
print(aa.alarm_name)  # AIS

上述结果说明,在类的方法内部试图修改类属性的值是愚蠢的做法,因为这个是可变的,这样会导致维护起来非常困难,一般建议通过 self 来传值



类的继承:  inheritance    
            Object  = Class(SuperClass)
                注意: 子类中在对  __init__ 内的变量在其他任何方法上做修改,内外值都会随着改变
                
            子类重写了父类的属性或者方法后,父类的信息都会改变
            
            多重继承:  class A  classB  c = classC(A,B) 顺序按照AB 顺序来
                Super() 调用显示父类的属性或函数  在重写的时候调用可以延续父类的属性或方法,子类可选是否借用父类
                        格式为: super(父类,参数self).__init__() 父类函数
            静态方法: 使用前提,需要一个参数不能让别人进行修改,在非特定环境下该静态变量或方法外部修改无效,只有在特定环境下修改才可行
                    如  IND = 'ON'        
                        class Kls(object):
                            def __init__(self, data):
                                self.data = data
                            @staticmethod  表明这是一个静态方法
                            def checkind():    
                                IND = "OFF"        ### 只有在这里修改才有效
                                return (IND == 'ON')   在别的地方也可以修改这个值 但是在调用这个方法的时候 IND 始终是OFF (已修改)  不会再有别的值
                            def do_reset(self):
                                IND = 'OFF'  ##这里修改无效
                                if self.checkind():
                                    print('Reset done for:', self.data)
                            def set_db(self):
                                if self.checkind():
                                    self.db = 'New db connection'
                                print('DB connection made for: ', self.data)
                                
            类方法: @classmethod 表示下面的方法是类方法  将类本身作为对象进行操作的方法
                     注意 必须至少有一个参数 cls 来代替 self  其余自定义
        
            多态: 著名的鸭子测试: 当我们看到一只鸟走起来像鸭子,游泳起来像鸭子,叫起来也像鸭子,那么这只鸟就可以被称为鸭子
                 意思是:一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前的方法属和属性的集合决定的。
                 注意: 类型检查是毁掉多态的利器   type() isinstance()  issubclass()  慎用!
            
        
        类的封装和私有化: 方法 或者属性 前面添加上 __ 即可 这样的话外部无法访问,但可以通过方法来访问
                如果想在外部访问私有属性或方法前添加上 @property 可以直接访问 对象.属性
                    class Person:
                        __age = int()
                        def __init__(self,name):
                            self.name = name
                            self.__age = 10

                        @property    #################这里可以直接访问到了
                        def age(self):
                            print(self.name,' 的年龄是:',self.__age)



猜你喜欢

转载自blog.csdn.net/guoxinjie17/article/details/77850385
今日推荐