Python高级培训-第二次任务

动态给实例添加属性和方法并使用

from types import  MethodType #引入包 使类外部方法可以调用
#创建一个类
class Cat(object):
    name = "Tom"
    def __init__(self): #初始化
        pass



c=Cat()
#动态添加属性,体现了语言的的特点(灵活)
c.run = "猫在跑"
print(c.run)#打印显示属性
#动态的添加方法
def Run(self):
    print(self.name+"在跑步")
#类似于偏函数
c.exercise = MethodType(Run,c) #为将Run方法传值给c对象 并将其赋值给c.exercise属性
c.exercise() #调用c.exercise属性

#如果我们想要限制实例的属性怎么办?
#比如:只允许给对象添加name、age、height、weight属性
#解决:定义类的时候,定义一个特殊的属性(__slots__),该属性可以限制动态添加的属性
#__slots__ = ("name","age","Run") 在括号里的内容是可以添加的属性

限制访问对象及访问方法 property的用法

property的用法详见:Python property() 函数 | 菜鸟教程

property() 函数的作用是在新式类中返回属性值。

语法

以下是 property() 方法的语法:

class property([fget[, fset[, fdel[, doc]]]])

参数

  • fget -- 获取属性值的函数
  • fset -- 设置属性值的函数
  • fdel -- 删除属性值函数
  • doc -- 属性描述信息

返回值

返回新式类属性。

class Person(object):
    def __init__(self,age):

        #1属性直接对外暴露
        #1self.age=age
        #限制访问
        self.__age=age

    #2通过get,set方法访问age
    def getAge(self):
        return self.__age
    def setAge(self, age):
        if age < 0:
            age = 0
        self.__age = age

    #3想要用点的形式去访问 受限制对象的方法
    #方法名为受限制的变量去掉双下划綫
    #property 可以让你对受限制访问的属性使用点语法
    @property
    def age(self):
        return self.__age
    @age.setter  #去掉下划线的方法名字.setter
    def age(self,age):
        if age < 0:
            age = 0
        self.__age = age

per = Person(18)

#1属性直接对外暴露
#不安全,且没事数据过滤
per.age=-10
print(per.age)

#2使用限制访问,需要自己写set和get方法才能访问
per.setAge(15)
print(per.getAge())

#3想要用点的形式去访问 受限制对象
per.age=100  #相当于调用setAge
print(per.age) #相当于调用getAge

运算符重载

 运算符重载:
        什么是运算符重载
            让自定义的类生成的对象(实例)能够使用运算符进行操作
        作用:
            让自定义的实例像内建对象一样进行运算符操作
            让程序简洁易读
            对自定义对象将运算符赋予新的规则

详细看:python之运算符重载_python -学习笔记-CSDN博客_python运算符重载

#不同的类型用加法会有不同的解释
print(1+2)
print("1"+"2")

class Person(object):
    def __init__(self,num):
        self.num = num

    #运算符重载
    #self代表“+”前边的对象(per1) other代表“+”后边的对象(per2)
    def __add__(self, other):
        return Person(self.num + other.num)
    def __str__(self):
        return "num = " + str(self.num) #self.num为数字型 str()转换成字符串



per1=Person(1)
per2=Person(2)
print(per1+per2) #per1+per2 === per1.__add__(per2)
print(per1.__add__(per2))
# 创建一个类
class Grade(object):
    def __init__(self, num): #初始化
        self.num = num

    # 运算符重载
    # self代表想要运算的数字 other代表次幂
    def __pow__(self, other):
        return self.num ** other.num

    def __str__(self):
        return "num = " + str(self.num)  # self.num为数字型 str()转换成字符串

    # #判断gra1的值是否<gra2
    def __lt__(self, other):
        return self.num < other.num
    # #判断gra1的值是否<=gra2
    def __le__(self, other):
        return self.num <= other.num
    # #判断gra1的值是否==gra2
    def __eq__(self, other):
        return self.num == other.num
    # #判断gra1的值是否!=gra2
    def __ne__(self, other):
        return self.num != other.num
    # #判断gra1的值是否>gra2
    def __gt__(self, other):
        return self.num > other.num
    # #判断gra1的值是否>=gra2
    def __ge__(self, other):
        return self.num >= other.num

grade1 = Grade(3) #实例化对象 并赋值给grade1
grade2 = Grade(4) #实例化对象 并赋值给grade2
grade3 = Grade(2) #实例化对象 并赋值给grade3
gra1=grade1.__pow__(grade3) #将grade1平方之后的数字赋值给gra1
gra2=grade2.__pow__(grade3) #将grade2平方之后的数字赋值给gra2
print("grade1的平方为 "+ str(grade1.__pow__(grade3))) #输出grade1平方之后的数字
print("grade2的平方为 "+ str(grade2.__pow__(grade3))) #输出grade2平方之后的数字
print("gra1的值是否<gra2 "+str(gra1.__lt__(gra2))) #判断gra1的值是否<gra2
print("gra1的值是否<=gra2 "+str(gra1.__le__(gra2))) #判断gra1的值是否<=gra2
print("gra1的值是否==gra2 "+str(gra1.__eq__(gra2))) #判断gra1的值是否==gra2
print("gra1的值是否!=gra2 "+str(gra1.__ne__(gra2))) #判断gra1的值是否!=gra2
print("gra1的值是否>gra2 "+str(gra1.__gt__(gra2))) #判断gra1的值是否>gra2
print("gra1的值是否>=gra2 "+str(gra1.__ge__(gra2))) #判断gra1的值是否>=gra2

Python3 操作符重载方法

原文: Python3 操作符重载方法_Luzhuo 的博客-CSDN博客_python3 重载运算符

#coding=utf-8
# specialfuns.py 操作符重载方法
# 类(class)通过使用特殊名称的方法(__len__(self))来实现被特殊语法(len())的调用

# 构造 与 析构 方法
class demo1:

    # 构造方法, 对象实例化时调用
    def __init__(self):
        print("构造方法")

    # 析构方法, 对象被回收时调用
    def __del__(self):
        print("析构方法")


# new
class demo2(object):
    # __init__之前调用, 一般用于重写父类的__new__方法, 具体使用见 类 文章的 元类 代码部分(http://blog.csdn.net/rozol/article/details/69317339)
    def __new__(cls):
        print("new")
        return object.__new__(cls)


# 算术运算
class demo3:
    def __init__(self, num):
        self.data = num
    # +
    def __add__(self, other):
        return self.data + other.data
    # -
    def __sub__(self, other):
        return self.data - other.data
    # *
    def __mul__(self, other):
        return self.data * other.data
    # /
    def __truediv__(self, other):
        return self.data / other.data
    # //
    def __floordiv__(self, other):
        return self.data // other.data
    # %
    def __mod__(self, other):
        return self.data % other.data
    # divmod()
    def __divmod__(self, other):
        # 商(10/5),余数(10%5)
        return self.data / other.data, self.data % other.data
    # **
    def __pow__(self, other):
        return self.data ** other.data
    # <<
    def __lshift__(self, other):
        return self.data << other.data
    # >>
    def __rshift__(self, other):
        return self.data >> other.data
    # &
    def __and__(self, other):
        return self.data & other.data
    # ^
    def __xor__(self, other):
        return self.data ^ other.data
    # |
    def __or__(self, other):
        return self.data | other.data


class none:
    def __init__(self, num):
        self.data = num
# 反算术运算符(a+b, 若a不支持算术运算符,则寻找b的算术运算符)(注:位置变换, 在原始函数名前+r)
class demo4:
    def __init__(self, num):
        self.data = num
    # +
    def __radd__(self, other):
        return other.data + self.data
    # -
    def __rsub__(self, other):
        return other.data - self.data
    # *
    def __rmul__(self, other):
        return other.data * self.data
    # /
    def __rtruediv__(self, other):
        return other.data / self.data
    # //
    def __rfloordiv__(self, other):
        return other.data // self.data
    # %
    def __rmod__(self, other):
        return other.data % self.data
    # divmod()
    def __rdivmod__(self, other):
        return other.data / self.data, other.data % self.data
    # **
    def __rpow__(self, other):
        return other.data ** self.data
    # <<
    def __rlshift__(self, other):
        return other.data << self.data
    # >>
    def __rrshift__(self, other):
        return other.data >> self.data
    # &
    def __rand__(self, other):
        return other.data & self.data
    # ^
    def __rxor__(self, other):
        return other.data ^ self.data
    # |
    def __ror__(self, other):
        return other.data | self.data


# 增量赋值运算,(注:位置同原始函数,在原始函数名前+i)
class demo5():
    def __init__(self, num):
        self.data = num
    # +=
    def __iadd__(self, other):
        return self.data + other
    # -=
    def __isub__(self, other):
        return self.data - other
    # *=
    def __imul__(self, other):
        return self.data * other
    # /=
    def __itruediv__(self, other):
        return self.data / other
    # //=
    def __ifloordiv__(self, other):
        return self.data // other
    # %=
    def __imod__(self, other):
        return self.data % other
    # **=
    def __ipow__(self, other):
        return self.data ** other
    # <<=
    def __ilshift__(self, other):
        return self.data << other
    # >>=
    def __irshift__(self, other):
        return self.data >> other
    # &=
    def __iand__(self, other):
        return self.data & other
    # ^=
    def __ixor__(self, other):
        return self.data ^ other
    # |=
    def __ior__(self, other):
        return self.data | other

# 比较运算符
class demo6:
    def __init__(self, num):
        self.data = num
    # <
    def __lt__(self, other):
        return self.data < other.data
    # <=
    def __le__(self, other):
        return self.data <= other.data
    # ==
    def __eq__(self, other):
        return self.data == other.data
    # !=
    def __ne__(self, other):
        return self.data != other.data
    # >
    def __gt__(self, other):
        return self.data > other.data
    # >=
    def __ge__(self, other):
        return self.data >= other.data


# 一元操作符
class demo7:
    def __init__(self, num):
        self.data = num
    # + 正号
    def __pos__(self):
        return +abs(self.data)
    # - 负号
    def __neg__(self):
        return -abs(self.data)
    # abs() 绝对值
    def __abs__(self):
        return abs(self.data)
    # ~ 按位取反
    def __invert__(self):
        return ~self.data
    # complex() 字符转数字
    def __complex__(self):
        return 1+2j
    # int() 转为整数
    def __int__(self):
        return 123
    # float() 转为浮点数
    def __float__(self):
        return 1.23
    # round()  近似值
    def __round__(self):
        return 1.123


# 格式化
class demo8:
    # print() 打印
    def __str__(self):
        return "This is the demo."
    # repr() 对象字符串表示
    def __repr__(self):
        return "This is a demo."
    # bytes() 对象字节字符串表现形式
    def __bytes__(self):
        return b"This is one demo."
    # format() 格式化
    def __format__(self, format_spec):
        return self.__str__()



# 属性访问
class demo9:
    # 获取(不存在)属性
    def __getattr__(self):
        print ("访问的属性不存在")
    # getattr() hasattr() 获取属性
    def __getattribute__(self, attr):
        print ("访问的属性是%s"%attr)
        return attr
    # setattr() 设置属性
    def __setattr__(self, attr, value):
        print ("设置 %s 属性值为 %s"%(attr, value))
    # delattr() 删除属性
    def __delattr__(self, attr):
        print ("删除 %s 属性"%attr)

# ===================================================================
# 描述器(类(test1)的实例出现在属主类(runtest)中,这些方法才会调用)(注:函数调用,这些方法不会被调用)
class test1:
    def __init__(self, value = 1):
        self.value = value * 2
    def __set__(self, instance, value):
        print("set %s %s %s"%(self, instance, value))
        self.value = value * 2
    def __get__(self, instance, owner):
        print("get %s %s %s"%(self, instance, owner))
        return self.value
    def __delete__(self, instance):
        print("delete %s %s"%(self, instance))
        del self.value

class test2:
    def __init__(self, value = 1):
        self.value = value + 0.3
    def __set__(self, instance, value):
        print("set %s %s %s"%(self, instance, value))
        instance.t1 = value + 0.3
    def __get__(self, instance, owner):
        print("get %s %s %s"%(self, instance, owner))
        return instance.t1
    def __delete__(self, instance):
        print("delete %s %s"%(self, instance))
        del self.value

class runtest:
    t1 = test1()
    t2 = test2()

# ---

# 自定义property
class property_my:
    def __init__(self, fget=None, fset=None, fdel=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
    # 对象被获取(self自身, instance调用该对象的对象(demo9), owner调用该对象的对象类对象(demo9))
    def __get__(self, instance, owner):
        print("get %s %s %s"%(self, instance, owner))
        return self.fget(instance)
    # 对象被设置属性时
    def __set__(self, instance, value):
        print("set %s %s %s"%(self, instance, value))
        self.fset(instance, value)
    # 对象被删除时
    def __delete__(self, instance):
        print("delete %s %s"%(self, instance))
        self.fdel(instance)

class demo10:
    def __init__(self):
        self.num = None
    def setvalue(self, value):
        self.num = value
    def getvalue(self):
        return self.num
    def delete(self):
        del self.num
    x = property_my(getvalue, setvalue, delete)

# ===================================================================

# 自定义容器
class lis:
    def __init__(self, *args):
        self.lists = args
        self.size = len(args)
        self.startindex = 0
        self.endindex = self.size
    # len() 容器元素数量
    def __len__(self):
        return self.size;
    # lis[1] 获取元素
    def __getitem__(self, key = 0):
        return self.lists[key]
    # lis[1] = value 设置元素
    def __setitem__(self, key, value):
        pass
    # del lis[1] 删除元素
    def __delitem__(self, key):
        pass
    # 返回迭代器
    def __iter__(self):
        return self
    # rversed() 反向迭代器
    def __reversed__(self):
        while self.endindex > 0:
            self.endindex -= 1
            yield self[self.endindex]
    # next() 迭代器下个元素
    def __next__(self):
        if self.startindex >= self.size:
            raise StopIteration # 控制迭代器结束

        elem = self.lists[self.startindex]
        self.startindex += 1
        return elem

    # in / not in
    def __contains__(self, item):
        for i in self.lists:
            if i == item:
                return True
        return False


# yield 生成器(执行一次返回,下次继续执行后续代码返回)
def yielddemo():
    num = 0
    while 1: # 1 == True; 0 == False
        if num >= 10:
            raise StopIteration
        num += 1
        yield num

# 能接收数据的生成器
def yielddemo_1():
    while 1:
        num = yield
        print(num)


# with 自动上下文管理
class withdemo:
    def __init__(self, value):
        self.value = value
    # 返回值为 as 之后的值
    def __enter__(self):
        return self.value
    # 执行完成,退出时的数据清理动作
    def __exit__(self, exc_type, exc_value, traceback):
        del self.value


if __name__ == "__main__":
    # 构造与析构
    d1 = demo1()
    del d1


    # new
    d2 = demo2()


    # 算术运算符
    d3 = demo3(3)
    d3_1 = demo3(5)
    print(d3 + d3_1)
    print(d3 - d3_1)
    print(d3 * d3_1)
    print(d3 / d3_1)
    print(d3 // d3_1)
    print(d3 % d3_1)
    print(divmod(d3, d3_1))
    print(d3 ** d3_1)
    print(d3 << d3_1)
    print(d3 >> d3_1)
    print(d3 & d3_1)
    print(d3 ^ d3_1)
    print(d3 | d3_1)


    # 反运算符
    d4 = none(3)
    d4_1 = demo4(5)
    print(d4 + d4_1)
    print(d4 - d4_1)
    print(d4 * d4_1)
    print(d4 / d4_1)
    print(d4 // d4_1)
    print(d4 % d4_1)
    print(divmod(d4, d4_1))
    print(d4 ** d4_1)
    print(d4 << d4_1)
    print(d4 >> d4_1)
    print(d4 & d4_1)
    print(d4 ^ d4_1)
    print(d4 | d4_1)


    # 增量赋值运算(测试时注释其他代码)
    d5 = demo5(3)
    d5 <<= 5
    d5 >>= 5
    d5 &= 5
    d5 ^= 5
    d5 |= 5
    d5 += 5
    d5 -= 5
    d5 *= 5
    d5 /= 5
    d5 //= 5
    d5 %= 5
    d5 **= 5
    print(d5)


    # 比较运算符
    d6 = demo6(3)
    d6_1 = demo6(5)
    print(d6 < d6_1)
    print(d6 <= d6_1)
    print(d6 == d6_1)
    print(d6 != d6_1)
    print(d6 > d6_1)
    print(d6 >= d6_1)


    # 一元操作符(测试时注释其他代码)
    d7 = demo7(-5)
    num = +d7
    num = -d7
    num = abs(d7)
    num = ~d7
    print(num)
    print(complex(d7))
    print(int(d7))
    print(float(d7))
    print(round(d7))


    # 格式化
    d8 = demo8()
    print(d8)
    print(repr(d8))
    print(bytes(d8))
    print(format(d8, ""))


    # 属性访问
    d9 = demo9()
    setattr(d9, "a", 1) # => 设置 a 属性值为 1
    print(getattr(d9, "a")) # => a / 访问的属性是a
    print(hasattr(d9, "a")) # => True / 访问的属性是a
    delattr(d9, "a") # 删除 a 属性
    # ---
    d9.x = 100 # => 设置 x 属性值为 100
    print(d9.x) # => x / 访问的属性是x
    del d9.x # => 删除 x 属性


    # 描述器
    r = runtest()
    r.t1 = 100 # =>  <__main__.test1> <__main__.runtest> 100
    print(r.t1) # => 200 /  <__main__.test1> <__main__.runtest> <class '__main__.runtest'>
    del r.t1 # =>  <__main__.test1> <__main__.runtest>
    r.t2 = 200 # => <__main__.test2> <__main__.runtest> 200 / <__main__.test1> <__main__.runtest> 200.3
    print(r.t2) # => 400.6 / <__main__.test2> <__main__.runtest> <class '__main__.runtest'> /  <__main__.test1> <__main__.runtest> <class '__main__.runtest'>
    del r.t2 # <__main__.test2> <__main__.runtest>
    # ---
    # 自定义property
    d10 = demo10()
    d10.x = 100; # => <__main__.property_my> <__main__.demo10> 100
    print(d10.x) # => 100 / <__main__.property_my> <__main__.demo10> <class '__main__.demo10'>
    del d10.x # => <__main__.property_my> <__main__.demo10>
    d10.num = 200;
    print(d10.num) # => 200
    del d10.num


    # 自定义容器(迭代器Iterator)
    lis = lis(1,2,3,4,5,6)
    print(len(lis))
    print(lis[1])
    print(next(lis))
    print(next(lis))
    print(next(lis))
    for i in lis:
        print (i)
    for i in reversed(lis):
        print (i)
    print(3 in lis)
    print(7 in lis)
    print(3 not in lis)
    print(7 not in lis)


    # yield 生成器(可迭代对象Iterable)
    for i in yielddemo():
        print (i)
    # ---
    iters = iter(yielddemo())
    print(next(iters))
    print(next(iters))

    # --- 发送数据给生成器 ---
    iters = yielddemo_1()
    next(iters)
    iters.send(6) # 发送数据并执行
    iters.send(10)


    # with 自动上下文管理
    with withdemo("Less is more!") as s:
        print(s)

 还可以参考:operator --- 标准运算符替代函数 — Python 3.10.1 文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值