类与对象

这是一节面向对象编程

python里的面向对象编程规则有着些许变化


  • 前面知道,python不同于Java,它是动态语言,它的对象可以自由地绑定任何属性,而Java只能操作对象里定义过的变量,例如:

      class Student(Object):
          def __init__(self,name,age):
              self.__name=name
              self.__age=age
    

    这里定义的Student对象,继承于Object对象,
    init()函数是Student类的特殊函数,它起着初始化的作用


    student1 = Student("hugo",22)
    

    根据__init__()函数的传参要求,这样就可以实例化一个对象
    注意,self的传参已被省略,这是python的特性,self 指的就是实例化的对象

    而 self.__name 和 self.__age 就是 self 对象自由绑定的两个属性,__name 的命名规则,表示这是私有变量,相当于 java 里的private

    print(student1.__name)
    # AttributeError: 'Student' object has no attribute '__name'
    直接访问会报错
    

    但是,我们知道,python没有任何机制去保护某个变量的私有性,也就是,这个变量其实是可以在对象外访问的,只是它在执行时,被python解释器隐藏了其真名,某些版本可以用

    student1._Student__name 访问到,但不同版本真名隐藏方式不同,所以不要这样搞

    其次再看体现自由绑定的特点,self 其实上面都没有,但硬是搞了俩 self.__name 和 self.__age 变量,还可以

    student1.gender = "male"
    #这是成立的,相当于给 student1对象绑定了一个属性
    

    但这种绑定仅限于实例化之后的对象,比如

    student2 = Student("yuchen",22)
    student1 = Student("yuchen")
    print(hasattr(student1,"age"))
    #True
    print(hasattr(student2,"age"))
    #False
    

    dir命令可以查明原因

      print(dir(student1))
    

    ['_Student__name', 'class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', 'init_subclass', 'le', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', 'age', 'count']

    这两个属性,一个说明__name变量名被改了,一个说明age被绑定到student1对象了


接下来补充一些用法和语法

  • 获取对象信息

    • type():直接查看对象名,可以应用到基本类型,以及函数类型,例如:
          import types 
          type("123")     #<class 'int'>
          type(123)       #<class 'str'>
          type(abs)       #<class 'builtin_function_or_method'>
          type(123)==type('123')  #False
          
          def fn():
              pass
          type(fn)==types.FunctionType       #True
          type(abs)==types.BuiltinFunctionType    #True
          type(lambda x:x*x)==types.LambdaType    #True
          type((x*x for x in range(1,10)))==types.GeneratorType   #True
      
      
    • isinstance():直接判断是否是某对象,还可以判断是否是某个对象的子孙,例如:
         class dog(Object):
            def __init__(self):
                self.name='dog'
        d=dog()
        isinstance(d,"dog")     #True
        isinstance(d,"Object")      #True
        isinstance(d,(list,dog))        #True
        一般来说,优先使用 isinstance() 可以判断一个家族
    
    • getattr(),setattr(),hasattr()
          class dog(Object):
              def __init__(self):
                  self.name='dog'
          d=dog()
          hasattr(d,"name")       #True
          hasattr(d,"age")        #False
          getattr(d,"name")       #dog
          setattr(d,"age","3")        #设置了一个属性'age'
          这里和对象的自由绑定作用很相似,但用法有不同,自由绑定不管三七二十一,硬是绑,但如果有些场景不能直接暴力插入,比如与类属性重名,这种命名冲突,不会报错,但会产生预想不到的bug,这种bug找都找不到。
      
posted @ 2023-01-11 20:24  HugoWang010220  阅读(34)  评论(0)    收藏  举报