基本用法
python3.x 新式类 python2.x 旧式类, 新式类不需要每次都写一次object,默认继承 作用:控制创建的对象,
class MyClass2(): abc = 1 obj2 = MyClass2() class MyClass(object): def __new__(cls): print(cls) # <class '__main__.MyClass'> # 借助object父类方法里面__new__ 来为本类创建一个对象 # return object.__new__(cls) # 返回一个本类对象 # return None # 返回一个空对象 # return obj2 # 返回的是一个其他类的对象 pass # 实例化对象obj # obj = MyClass() # print(obj) # print(obj.abc)对比 __new__ 和 __init__ 的触发时机
__new__ 魔术方法是用来创建对象的 __init__魔术方法是用来初始化对象的 得先有对象,才能够初始化,没有对象初始化谁? __new__ 的触发时机要快于__init__
__new__ __init__ 这两个方法的参数要一一匹配.
# (1) 一个参数 class Boat(): def __new__(cls, name): print(1) return object.__new__(cls) def __init__(self, name): self.name = name obj = Boat("大锤") # (2) 无限个参数 class Boat(): def __new__(cls, *args, **kwargs): print(1) return object.__new__(cls) def __init__(self, *args, **kwargs): strvar = "" for i in args: strvar += i + " " print("小船的贡献者有:", strvar) print("小船的名字是{}".format(kwargs['name'])) obj = Boat("王俊文", "舒畅", "境泽年", "五金玲", name="Anglelababy") 如果通过__new__返回的是其他类的对象,不会触发自己本类的__init__ ‘’‘因为__init__初始化的是本类对象’’’ class Boat(): def __new__(cls, *args, **kwargs): return obj2 def __init__(self): print("init调用了") obj = Boat() print(obj.abc)所有对象被del的时候
只有当所有指向该对象的变量都删除的时候,才算真正的删除该对象
obj2 = obj print("<==start===>") del obj del obj2 print("<==end===>") 用类来模拟文件写的操作 fp = open("ceshi111.txt",mode="w",encoding="utf-8") fp.write("sfdsdf") fp.close() fp = open("ceshi111.txt",mode="r",encoding="utf-8") res = fp.read() fp.close() print(res) print("<=111==>") class MyFile(): # 判断是否创建MyFile该对象 def __new__(cls, filename): if os.path.exists(filename): return object.__new__(cls) return print("该文件不存在") # 产生文件对象 def __init__(self, filename): self.fp = open(filename, mode="r", encoding="utf-8") # 读取文件 def readfile(self): res = self.fp.read() return res def __del__(self): print(0) # 自动触发__del__ ,帮助我们关闭文件 self.fp.close() obj = MyFile("ceshi222.txt") res = obj.readfile() print(res)1.基本语法
class MyClass(): def __call__(self): print("__call__方法被调用") return "done" obj = MyClass() res = obj() print(res) 模拟洗衣服的过程 class Wash(): # 使用call方法,进行统一的调用 def __call__(self, something): self.something = something print("以下是洗{}的过程:".format(something)) self.step1() self.step2() self.step3() def step1(self): print("第一步放水,把{}扔盆里".format(self.something)) def step2(self): print("第二部导入洗衣液,金纺,蓝月亮,吊牌洗衣皂扔盆里搓") def step3(self): print("第三部晒一下,穿上") obj = Wash() # 一边写一边骂街 # obj.step1() # obj.step2() # obj.step3() # 小王是个快乐的孩子 obj("裤衩") 模拟内置int方法实现myint # print(int(-5.9)) import math class MyInt(): def stoi(self, n, sign=1): res = n.lstrip("0") if res == "": return 0 num = eval(res) * sign return num def __call__(self, n): # 判断的是布尔类型 if isinstance(n, bool): if n: return 1 else: return 0 # 判断的是整型 elif isinstance(n, int): return n # 判断的是浮点型 elif isinstance(n, float): if n < 0: return math.ceil(n) else: return math.floor(n) # 判断的是字符串 elif isinstance(n, str): if (n[0] == "-" or n[0] == "+") and n[1:].isdecimal(): if n[0] == "+": sign = 1 elif n[0] == "-": sign = -1 return self.stoi(n[1:], sign) elif n.isdecimal(): # 如果能够走到这个条件,一定没有带任何正负号 return self.stoi(n) else: return "对不起,老弟,这个算不了" else: print("对不起,老哥,这个算不了") myint = MyInt() res = myint(False) print(res) res = myint(5) print(res) res = myint(-5.5) print(res) # res = eval("123454") # print(res,type(res)) res = myint("12345") print(res,type(res)) # res = int("-00000000000111222abcdfrf") # print(res) res = myint("+00000000000111222") res = myint("*&^%$#@00000000000000000") print(res) # res = int("*&^%$#@00000000000000000") # res = eval("") # print(res) res = int(5 + 6) print(res) res = myint(5 * 6) print(res) res = myint([1,3,4]) res = int([1, 3, 4]) print(res)类似的还有如下等等(了解): __complex__(self) 被complex强转对象时调用 __int__(self) 被int强转对象时调用 __float__(self) 被float强转对象时调用 … …
class MyBool(): def __bool__(self): print(122) # return True return False obj = MyBool() res = bool(obj) print(res)(与之相关的__radd__ 反向加法)
触发时机:使用对象进行运算相加的时候自动触发功能:对象运算参数:二个对象参数返回值:运算后的值类似的还有如下等等(了解): __sub__(self, other) 定义减法的行为:- __mul__(self, other) 定义乘法的行为:* __truediv__(self, other) 定义真除法的行为:/ … …
class MyAdd(): def __init__(self, num): self.num = num # 对象+数值,并且对象在+加号的左边,自动触发__add__方法 def __add__(self, other): # self.num => 3 + 56 => 59 return self.num + other def __radd__(self, other): # self 接受b, other 接受33 return self.num + other * 10 # 1.当对象在加号的左侧 自动触发add 方法 a = MyAdd(3) res = a + 56 print(res) # 2.当对象在加号的右侧 自动触发radd 方法 b = MyAdd(5) res = 33 + b print(res) # 3 a+b =? res = a + b print(res) ''' a在加号的左侧,触发add魔术方法 self.num + other => 3 + b b在加号的右侧,触发radd魔术方法 res = 3+b self.num + other * 10 => 5 + 3 *10 => 35 '''类似的还有如下等等(了解): __iter__(self) 定义迭代容器中的元素的行为 __reversed__(self) 定义当被 reversed() 调用时的行为 __contains__(self, item) 定义当使用成员测试运算符(in 或 not in)时的行为 … …
用len(对象)方式,算出该对象所归属的类有多少自定义成员
class MyLen(): pty1 = 1 pty2 = 2 __pty3 = 3 def func1(): pass def func2(): pass def __func3(): pass def __func4(): pass def __func5(): pass def __len__(self): # print(MyLen.__dict__) dic = MyLen.__dict__ lst = [i for i in dic if not(i.startswith("__") and i.endswith("__"))] num = len(lst) return num obj = MyLen() res = len(obj) print(res) """ {'__module__': '__main__', 'pty1': 1, 'pty2': 2, '_MyLen__pty3': 3, 'func1': <function MyLen.func1 at 0x7f10880d9620>, 'func2': <function MyLen.func2 at 0x7f10880d96a8>, '_MyLen__func3': <function MyLen.__func3 at 0x7f10880d9730>, '__len__': <function MyLen.__len__ at 0x7f10880d97b8>, '__dict__': <attribute '__dict__' of 'MyLen' objects>, '__weakref__': <attribute '__weakref__' of 'MyLen' objects>, '__doc__': None} """