python模块

  1. 针对 __str__ 方法给出一个比较直观的例子:

    class people:
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
        def __str__(self):
            return '这个人的名字是%s,已经有%d岁了!'%(self.name,self.age)
    
    a=people('孙悟空',999)
    print(a)

    输出:

    这个人的名字是孙悟空,已经有999岁了!
    如果没有重载函数的话输出的就是一串看不懂的字符串:
    <__main__.people object at 0x00000272A730D278>
  2. Python3 中类的静态方法、普通方法、类方法

    静态方法: 用 @staticmethod 装饰的不带 self 参数的方法叫做静态方法,类的静态方法可以没有参数,可以直接使用类名调用。

    普通方法: 默认有个self参数,且只能被对象调用。

    类方法: 默认有个 cls 参数,可以被类和对象调用,需要加上 @classmethod 装饰器。

    class Classname:
        @staticmethod
        def fun():
            print('静态方法')
    
        @classmethod
        def a(cls):
            print('类方法')
    
        # 普通方法
        def b(self):
            print('普通方法')
    
    
    
    Classname.fun()
    Classname.a()
    
    C = Classname()
    C.fun()
    C.a()
    C.b()
  3. 反向运算符重载:

    • __radd__: 加运算
    • __rsub__: 减运算
    • __rmul__: 乘运算
    • __rdiv__: 除运算
    • __rmod__: 求余运算
    • __rpow__: 乘方

    复合重载运算符:

    • __iadd__: 加运算
    • __isub__: 减运算
    • __imul__: 乘运算
    • __idiv__: 除运算
    • __imod__: 求余运算
    • __ipow__: 乘方
  4. Python3 类方法总结

    •  普通方法:对象访问
    •  私有方法:两个下划线开头,只能在类内部访问
    •  静态方法:类和对象访问,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
    •  类方法:类和对象访问,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
    •  多继承情况下:从左到右查找方法,找到为止,不然就抛出异常
    class People:
    
        # 定义基本属性
        name=''
        age=0
        # 定义私有属性外部无法直接访问
        __weight=0
        def __init__(self,n,a,w):
            self.name = n
            self.age = a
            self.__weight = w
        def speak(self):
            print("%s say : i am %d."%(self.name,self.age))
    p = People('Python',10,20)
    p.speak()
    # __weight无法直接访问
    print(p.name,'--',p.age)#,'--',p.__weight)

    继承

    单继承:

    class Student(People):
        grade=''
        def __init__(self,n,a,w,g):
            People.__init__(self,n,a,w)
            self.grade = g
    
        # 覆写父类方法
        def speak():
            print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
    
    class Speak():
        topic=''
        name=''
        def __init__(self,n,t):
            self.name = n
            self.topic = t
        # 普通方法,对象调用
        def speak(self):
            print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
    
        # 私有方法,self调用
        def __song(self):
            print('唱一首歌自己听',self);
    
        # 静态方法,对象和类调用,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
        @staticmethod
        def song():
            print('唱一首歌给类听:静态方法');
    
        # 普通方法,对象调用
        def song(self):
            print('唱一首歌给你们听',self);
            
        # 类方法,对象和类调用,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
        @classmethod
        def song(self):
            print('唱一首歌给类听:类方法',self)

    多继承:

    class Sample(Speak,Student):
        a = ''
        def __init__(self,n,a,w,g,t):
            Student.__init__(self,n,a,w,g)
            Speak.__init__(self,n,t)
    test = Sample('Song',24,56,7,'Python')
    test.speak()
    test.song()
    Sample.song()
    Sample.song()
    test.song()
    
    # test.__song() 无法访问私有方法
  5. 所有专有方法中,__init__()要求无返回值,或者返回 None。而其他方法,如__str__()、__add__()等,一般都是要返回值的,如下所示:

    >>> class Complex:
    ...     def __init__(self, realpart, imagpart):
    ...         self.r = realpart
    ...         self.i = imagpart
    ...         return 'hello'
    ...
    >>> x = Complex(3.0, -4.5)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: __init__() should return None, not 'str'

    而对于 __str__()、__add__() 等。

    def __str__(self):
            return 'Vector (%d, %d)' % (self.a, self.b)
    
    def __repr__(self):
        return 'Vector (%d, %d)' % (self.a, self.b)
    
    def __add__(self,other):
        if other.__class__ is Vector:
            return Vector(self.a + other.a, self.b + other.b)
        elif other.__class__ is int:
            return Vector(self.a+other,self.b)
  6.  类的专有方法中,也是存在默认优先级的,多个方法都有返回值,但一般优先取 __str__() 的返回值,如下面例子:

    类的专有方法中,也是存在默认优先级的,多个方法都有返回值,但一般优先取 __str__() 的返回值,如下面例子:
    class Vector:
        def __init__(self, a, b):
            self.a = a
            self.b = b
        def __repr__(self):
            return 'Vector (%d, %d)' % (self.b, self.a)
        def __str__(self):
            return 'Vector (%d, %d)' % (self.a, self.b)
        def __add__(self,other):
            return Vector(self.a + other.a, self.b + other.b)
    
    v1 = Vector(2,10)
    print (v1)

    结果是 Vector(2,10),而不是 Vector(10,2)。这里优先使用 __str__() 的返回值。

    v1.__repr__()

    结果是:Vector(10,2)

  7. __str__函数

    __str__ 是一个类的方法,在打印类对象,获取其属性信息时调用。打印一个实例化对象时,默认打印的其实时一个对象的地址,但是我们可以对其进行重载,打印我们想要的信息。例如上面的例子中进行的重载。

  8.  在类的方法中直接修改 self 是无效操作,即使 self 变量的地址与实例地址相同:

    class C:
      def __init__(self, a):
        self.a = a
      def construct(self, a):
        c = C(a)
        self = c
      def getid(self):
        return id(self)
    
    if __name__ == '__main__':
      c1 = C(2)
      c1.construct(3) # c1.a == 2
      print(id(c1) == c1.getid()) # True
  9. 事实上 class 的私有属性在外部也是可以访问的我们可以看下文中的例子。

    #!/usr/bin/python3
    class People:
        def __init__(self, name, age, ):
            self.name = name
            self.age = age
            self.__privater_var = 10  
      
        def intro(self):
            print(f'My name is {self.name},I\'m {self.age}')
    
        def get_var(self):
            print(self.__privater_var)
    
        def set_var(self, var):
            self.__privater_var = var
    
    someone = People(name='jack', age=20)
    someone.intro()
    print(someone.age)
    someone.get_var() # 通过get_var方法访问私有属性__privater_var,值为10
    someone.set_var(30) # 通过set_var方法修改私有属性__privater_var,值为30
    someone.get_var() # 再次通过get_var方法访问私有属性__privater_var,值为30

    结果:

    My name is jack,I'm 20
    20
    10
    30

    接下下来看看为什么我们使用someone.__privater_var会报错呢?

    AttributeError: 'People' object has no attribute '__privater_var'

    这里我们先使用 dir() 函数:

    print(dir(someone)) #  获得当前someone的属性列表

    结果:

    ['_People__privater_var', '__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', 'get_var', 'intro', 'name', 'set_var']

    从打印出的结果中,我们并没有找到'_peivater_var'但是我们看到一个'_People__privater_var'.有没有想到什么?原来是被重命名了。好,我们来试试:

    print(someone._People__privater_var)
    someone._People__privater_var = 40
    print(someone._People__privater_var)

    结果:

    30
    40

    所以说,私有变量的属性是可以修改的。既然Python阻止访问,一般情况下就不要访问。

posted @ 2020-11-29 20:56  富贵儿-  阅读(284)  评论(0编辑  收藏  举报