返回顶部
首页 > 资讯 > 后端开发 > Python >定制类和黑魔法
  • 315
分享到

定制类和黑魔法

黑魔法 2023-01-30 22:01:24 315人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

定制类  反射    反射又称为自省,指的是程序可以访问、检测和修改它本身状态和行为的一种能力。python中提供了以下四个自检功能的函数。    hasattr(object, name):用来检测object(适用于类、文件、模块或对

定制类
  反射
    反射又称为自省,指的是程序可以访问、检测和修改它本身状态和行为的一种能力。python中提供了以下四个自检功能的函数。
    hasattr(object, name):用来检测object(适用于类、文件、模块或对象,一切皆对象)中有没有一个name字符串对应的方法或属性。

>>> class Person:
...     def __init__(self, name, age):
...         self.name = name
...         self.age = age
...     def get_info(self):
...         return '%s的年龄是%s岁!'%(self.name, self.age)
... 
>>> p1 = Person('Jack', 22)
>>> p1.name    # 直接调用name属性
'Jack'
>>> p1.__dict__['name']    # name属性存放于__dict__中,name是字符串
'Jack'
>>> hasattr(p1, 'name')    # 判断p1中是否有name属性,name是字符串
True
>>> hasattr(p1, 'get_info')    # 方法属性也可判断,传入方法名的字符串
True
getattr(object, name, default=None):返回对象的name字符串对应的属性值或方法地址。
>>> getattr(p1, 'name')    # 返回name属性的值,等同于p1.name
'Jack'
>>> getattr(p1, 'age')
22
>>> getattr(p1, 'get_info')    # 返回方法的地址等同于p1.get_info
<bound method Person.get_info of <__main__.Person object at     0x10e51b860>>
>>> getattr(p1, 'sex')    # 若属性或方法不存在,而getattr又没有提供默认值,则报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Person' object has no attribute 'sex'
>>> getattr(p1, 'sex', 'male')# 若属性或方法不存在,而getattr提供了默认值,则返回默认值
'male'
setattr(object, key, value):给对象object的属性key赋值value,既可以新增属性也可以修改已有属性的值。
>>> setattr(p1, 'sex', 'male')    # 为对象p1新增sex属性,等同于p1.sex = ‘male’
>>> p1.__dict__
{'name': 'Jack', 'age': 22, 'sex': 'male'}
>>> setattr(p1, 'name', 'zhangsan')    # 修改p1对象已有属性name的值
>>> p1.__dict__
{'name': 'zhangsan', 'age': 22, 'sex': 'male'}
>>> setattr(p1, 'func', lambda x:x+1)    # 还可以增加对象的方法属性,为对象添加方法
>>> p1.__dict__
{'name': 'zhangsan', 'age': 22, 'func': <function <lambda> at 0x10e3f61e0>}
 delattr(object, name):删除对象object的name属性值。
>>> delattr(p1, 'sex')    # 删除对象p1的sex属性,等同于del p1.sex
>>> p1.__dict__
{'name': 'zhangsan', 'age': 22}

  注意:以上四个自省的函数,传入的对象的属性名都要以字符串的形式。

  类是对象,类也是对象类型。
  判断一个对象是否属于一个类,使用内建函数isinstance(),用它可以判断一个对象是否是一个类或者子类的实例;也可以判断一个对象是否是某个类型。

>>> isinstance(3, int)
True
>>> isinstance([2, 3], list)
True
>>> class A:
...     pass
... 
>>> a = A()
>>> isinstance(a, A)
True
  因此,创建了一个类就是创建了一种对象类型。


自定义对象类型: 自定义类,就要用到类的特殊方法,比如__init__()初始化方法;__str__()输出字符串方法;__add__()定义加法运算符等。
>>> class Fraction:
...     def __init__(self, num1, num2):
...         self.num1 = num1
...         self.num2 = num2
...     def __str__(self):
...         return str(self.num1) + '/' + str(self.num2)
...     __repr__ = __str__
...     def __add__(self, other):    # 魔术方法,实现加法运算符
...         return str(self.num1+other.num1) + '/' + str(self.num2+other.num2)
... 
>>> m = Fraction(2, 3)
>>> n = Fraction(5, 6)
>>> s = m + n    # 执行+号时自动调用__add__方法,相当于执行m.__add__(n)
>>> print(s)
7/9

  代码中__repr__ = __str__的含义是在被调用(实例化对象)时,向变量(即实例化的对象)提供__str__()里的内容。

  我们在代码中增加了特殊方法__add__(),它就是实现加法运算符的魔术方法。在Python中,运算符的作用是简化书写,实现运算的运算符都有其对应的特殊方法支撑才得以实现的。

常见运算符及其对应的特殊方法

二元运算符

特殊方法

+

__add__ , __radd__

-

__sub__ , __rsub__

*

__mul__ , __rmul__

/

__div__ , __rdiv__ , __truediv__ , __rtruediv__

//

__floordiv__ , __rfloordiv__

%

__mod__ , __rmod__

**

__pow__ , __rpow__

<<

__lshift__ , __rlshift__

>>

__rshift__ , __rrshift__

and

__and__ , __rand__

==

__eq__

!=

__ne__

>

__ge__

<

__lt__

>=

__ge__

<=

__le__

 

  以“+”为例,不论是实现“1 + 2”, 还是实现“[1, 3, ‘a’] + [4, ‘dd’]”,都会自动执行1.__add__(2)或者[1, 3, ‘a’].__add__([4, ‘dd’])操作。即两个对象是否能进行加法运算,首先要看对象是否有__add__()方法,一旦对象有__add__()方法,就可以定义对象的相加操作。

 

黑魔法

  优化内存

    我们知道类中有__dict__属性,它包含了当前类中的所有属性和方法;类的每个对象也有各自的__dict__属性,它包含了对应的对象中的属性。

>>> class Foo:
...     name = 'zhangsan'
...     age = 'male'
... 
>>> Foo.__dict__    # 类的__dict__属性
mappingproxy({'__module__': '__main__', 'name': 'zhangsan', 'age': 'male', '__dict__':     <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo'     objects>, '__doc__': None})
>>> f = Foo()
>>> f.__dict__    # 实例的__dict__属性
{}
>>> f.name = 'lisi'
>>> f.__dict__
{'name': 'lisi'}

  假设有无数个对象,则就会有无数个__dict__属性,这将占用很大的内存资源。需要一种能够控制__dict__的方法,这就是特殊属性__slots__。

>>> class spring:
...     __slots__ = ('tree', 'flower')    # 类中定义__slots__属性
... 
>>> dir(Spring)    # 类中的__dict__属性被__slots__属性替代
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__fORMat__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'flower', 'tree']
>>> Spring.__slots__
('tree', 'flower')
>>> Spring.tree = 'baiyang'
>>> Spring.tree
'baiyang'
>>> t = Spring()
>>> t.__slots__    # 实例中也是__slots__属性
('tree', 'flower')
>>> f = Spring()
>>> f.__slots__
('tree', 'flower')
>>> id(f)    # 实例的__slots__属性和类的__slots__属性都为同一个
4418820360
>>> id(t)
4418820304
>>> id(f.__slots__)
4418824584
>>> id(t.__slots__)
4418824584
>>> id(Spring.__slots__)
4418824584

   由以上代码可以看出,所有实例的__slots__属性与类的完全一样,这跟前面的__dict__属性大不一样了。内存中只有一个__slots__属性,再增加实例时__slots__属性不会增加。
  类属性赋值后,可以通过任何一个实例来调用它,但不能通过任何一个实例修改类属性的值。

>>> Spring.tree    # 赋值后的类属性可以通类名和对象调用
'baiyang'
>>> t.tree
'baiyang'
>>> f.tree
'baiyang'
>>> t.tree = 'xiangzhangshu'    # 实例不能修改类属性
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Spring' object attribute 'tree' is read-only
>>> Spring.tree = 'huyang'    # 可通过类名修改类属性

   类属性是静态属性,对实例来说,不能修改,是只读的,只能通过类名修改。
  对于尚未赋值的类属性名,实例可以定义与其同名的实例属性。

>>> t.flower = 'yuejihua'
>>> Spring.flower
<member 'flower' of 'Spring' objects>
>>> Spring.flower = 'guihua'
>>> Spring.flower
'guihua'
>>> t.flower
'guihua'

  由以上代码可以看出,实例属性没有传回到类属性中,这里只是实例建立了一个临时的与类属性同名的实例属性。定义了__slots__属性后,由于只有这么一个属性空间用来存放属性和方法,所以类属性对实例属性具有决定作用。因为操作实例属性会自动调用__setattr__方法,底层操作实例的__dict__属性字典,而定义了__slots__后,__dict__不存在了。
  __slots__属性是类和对象共用的,它把实例属性牢牢地管控起来,只能是定义类时指定的属性。如果要增加、修改属性,只能通过类来实现。它不像__dict__属性是类和每个对象都是自己独立的,可以存放各自的属性。
  __slots__总结:
    1.__slots__是什么:是一个类属性变量,变量值可以是列表、元组或者可迭代对象,也可以是一个字符串(意味着所有实例只有一个数据属性)。
    2.引子:使用点来访问属性本质上就是在访问类或者对象的__dict__属性字典(类的字典是共享的,而每个实例的是独立的)中的内容。
    3.为何使用__slots__:__dict__属性字典会占用大量内存。如果有一个属性很少的类,但是有很多实例,每个实例又不需要定义各自的实例属性,此时为了节省内存,可以使用__slots__取代__dict__。
    当定义__slots__后,__slots__就会为实例使用一种更加紧凑的内部表示。实例通过一个很小的固定大小的数组来构建,而不是为每个实例定义一个__dict__属性字典。
    使用__slots__一个不好的地方就是我们不能再给实例添加新的属性了,因为实例中已经没有了用来保存属性的__dict__字典,只能使用在__slots__中定义的那些属性,即类中的__slots__中定义了哪些属性,对象也只能使用那些属性,对象不能自己去创建新属性(因为没有了__dict__),也不能修改类的属性,因为受类控制。
    4.注意事项:__slots__的很多特性都依赖于普通的基于字典的实现。另外,定义了__slots__后的类不再支持一些普通类特性了,比如多继承。
    大多数情况下,应该只在那些经常被使用到的用作数据结构的类上定义__slots__,
    比如在程序中需要创建某个类的几百万个实例对象 。
    关于__slots__的一个常见误区是它可以作为一个封装工具来防止用户给实例增加新的属性。尽管使用__slots__可以达到这样的目的,但是这个并不是它的初衷。更多的是用来作为一个内存优化工具。


属性拦截
  当调用未定义的属性时,会直接报错,属性不存在。

>>> class A:
...     pass
... 
>>> a = A()
>>> a.x    # 变量x在类中没有定义,调用会报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'x'

  如果在调用类中未定义的属性时,我们希望有别的提示、操作等,而不希望等着报错,这时就用到了属性拦截。
  python中的具有属性拦截功能的方法:
    __setattr__(self, name, value):如果要给name赋值,就调用这个方法。
    __getattr__(self, name):如果name被访问,但它又不存在,则此方法被调用。
    __getattribute__(self, name):当name被访问时自动被调用,无论name是否存在,都会被调用。
    __delattr__(self, name):如果要删除name,则这个方法被调用。

>>> class A:
...     def __getattr__(self, name):    # 定义黑魔法__getattr__和__setattr__
...         print('You use getattr')
...     def __setattr__(self, name, value):
...         print('You use setattr')
...         self.__dict__[name] = value
... 
>>> a = A()
>>> a.x    # 属性x不存在,自动调用__getattr__,在__getattr__中做处理
You use getattr
>>> a.y = 9    # 增加属性并赋值,自动调用__setattr__,设置a.__dict__属性内容
You use setattr
>>> a.y    # 属性存在,不会调用__getattr__
9

  a.x的属性本来是不存在的,但由于类中有了__getattr__(self, name)方法,当发现属性x不存在于对象的__dict__中时,就调用了__getattr__,即属性拦截。
  给对象的属性赋值时,调用了__setattr__(self, name, value)方法,这个方法中有一句self.__dict__[name] = value,通过这个语句,就将属性和数据保存到了对象的__dict__中,而不用self.name = value,因为如果用self.name = value,只要一赋值就会自动触发__setattr__,导致无限递归
  也可以在类中定义__getattribute__(self, name),并且只要访问属性,不论该属性是否存在,都会自动调用它。当类中同时定义了__getattribute__(self, name)和__getattr__(self, name),而__getattribute__(self, name)中又没有抛出AttributeError异常时,__getattr__(self, name)将不起作用;当__getattribute__(self, name)中抛出了AttributeError异常,__getattribute__(self, name)执行到抛出异常语句时,会调用__getattr__(self, name)。当自定义了__getattribute__(self, name),且__getattribute__(self, name)中又抛出AttributeError异常时,可以定义__getattr__(self, name)配合__getattribute__(self, name)使用。还可以定义__delattr__(self, name),当删除属性时,不论要删除的属性是否存在,都自动调用该方法。

>>> class B: 
...     def __getattribute__(self, name):
...         print('You are using getattribute')
...         return object.__getattribute__(self, name)    # 通过这种方法返回属性值
...     def __delattr__(self, name):
...         print('You are using delattr')
... 
>>> b = B()
>>> b.x    # 属性不存在,也会调用__getattribute__,并报错
You are using getattribute
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __getattribute__
AttributeError: 'B' object has no attribute 'x'
>>> b.y = 3
>>> b.y    # 属性存在,也会调用__getattribute__
You are using getattribute
3
>>> del b.y    # 删除已存在的属性,调用__delattr__
You are using delattr
>>> del b.z    # 删除不存在的属性,也调用__delattr__
You are using delattr

  我们注意到上面的代码中,返回属性内容用的是return object.__getattribute__(self, name),而没有用return self.__dict__[name]的方式,是因为如果用self.__dict__[name]的方式,就是访问self.__dict__,只要访问这个属性,就会调用__getattribute__(),会导致无限递归。当新增属性并赋值后,属性就存在于__dict__中了,再调用时,依然会被拦截,但由于存在于__dict__中了,会将结果返回。以上黑魔法中的参数name就对应于对象或类中的属性。
  以上的黑魔法在建立类的时候,就会存在于类中,重新定义则会覆写类中原有的。需要注意的是,__setattr__会在给属性赋值时自动触发,所以在自定义的__setattr__方法中不能出现类似于self.key = value的形式的直接赋值操作,这样会陷入无限递归,应使用self.__dict__[key] = value的形式操作底层字典。同样的还有__delattr__,删除属性时会自动触发,因此在自定义的__delattr__方法中,不能出现类似于del self.key形式的直接删除,这样也会陷入无限递归,要用self.__dict__.pop(key)的操作底层字典的形式。__setattr__和__delattr__中的定义属于多此一举,不定义这两种方法也是在默认执行赋值或删除操作,因此很少使用。__getattr__用的较多。

结合属性拦截对字符串、列表、元组、字典的补充:
  由上面介绍的属性拦截可知在对象通过点(.)的方式操作属性会触发上面四种具有属性拦截功能的方法。而在序列(字符串、列表、元组)通过索引或字典通过键操作其元素时也会自动触发一些内置方法:__getitem__、__setitem__、__delitem__。同样的,对象通过键的方式操作属性时,也会触发上面的三种方法。需要注意的是,字符串和元组只能取出其元素,不等删除和修改元素,所以字符串和元组中只有__getitem__方法。
  __getitem__:在通过索引或键取出元素或属性时触发。
  __setitem__:在通过索引或键设置元素或属性时触发。
  __delitem__:在通过索引或键删除元素或属性时触发。

>>> class Foo:
...     def __getitem__(self, item):
...         print('通过键的方式取得对象属性')
...         return self.__dict__[item]
...     def __setitem__(self, key, value):
...         print('通过键的方式为对象属性赋值')
...         self.__dict__[key] = value
...     def __delitem__(self, key):
...         print('通过键的方式删除对象属性')
...         self.__dict__.pop(key)
... 
>>> foo = Foo()
>>> foo['x'] = 9    # 自动触发__setitem__方法 
通过键的方式为对象属性赋值
>>> foo['name'] = 'zhangsan'
通过键的方式为对象属性赋值
>>> foo['age'] = 'male'
通过键的方式为对象属性赋值
>>> print(foo.__dict__)
{'x': 9, 'name': 'zhangsan', 'age': 'male'}
>>> print(foo['name'])    # 自动触发__getitem__方法
通过键的方式取得对象属性
zhangsan
>>> del foo['age']    # 自动触发__delitem__方法
通过键的方式删除对象属性
>>> print(foo.__dict__)
{'x': 9, 'name': 'zhangsan'}

  注意:自定义的类,即使继承了python内置的类型(list、str、tuple、dict)等,也不会受其父类限制的影响,因为我们可以完全的去自定义子类,子类中可以增加父类没有的功能,对于继承了已有对象类型的子类,我们在操作__getitem__、__setitem__、delitem__属性时,必然会跟__dict__属性联系在一起,此时基本上已经脱离了list、str、tuple、dict父类的内容,大部分都是自身定义的内容。当然子类依然可以使用父类中的内容。


反射和黑魔法应用
  要在一个类中使用另一个类中的方法,可以利用继承的方式去实现,继承也可以实现覆写,即定义自己的同名方法。这里介绍利用组合的方式完成授权,同样实现在一个类中使用另一个类中的方法,并且可以重新定义同名方法。

import time
class HandleFile:
    def __init__(self, filename, mode='r', encoding='utf-8'):
        self.filename = filename
        self.mode = mode
        self.encoding = encoding
        self.file = open(filename, mode, encoding=encoding)    # 组合方式,将open类关联到自定义类HandleFile组合
    def write(self, item):    # 自定义write方法
        if not item.isdigit():    # 写入的内容不能全为数字
            t = time.localtime()    # 在写入的内容前加上写入的时间
            self.file.write(time.strftime('%Y-%m-%d %X', t)+': '+item)
        else:
            print('写入的内容不能全为数字!')

    def __getattr__(self, item):    # 定义__getattr__方法,当类中属性不存在时,自动调用
        print(item, type(item))    # 打印对象和对象的属性的类型
        return getattr(self.file, item)    # 调用对象关联的类中的方法

f = HandleFile('a.txt', 'w+')
f.write('11111111111')    # 调用自定义的write方法
f.write('abcde33fgh\n')
time.sleep(1)
f.write('learn python\n')
time.sleep(1)
f.write('Simple is better than complex\n')
f.seek(0)    # 通过__getattr__调用和对象关联的类中的方法
print(f.read())

写入的内容不能全为数字!
seek <class 'str'>    # 对象属性的类型是字符串
read <class 'str'>
2018-10-18 17:35:01: abcde33fgh
2018-10-18 17:35:02: learn python
2018-10-18 17:35:03: Simple is better than complex

 

--结束END--

本文标题: 定制类和黑魔法

本文链接: https://lsjlt.com/news/180227.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 定制类和黑魔法
    定制类  反射    反射又称为自省,指的是程序可以访问、检测和修改它本身状态和行为的一种能力。python中提供了以下四个自检功能的函数。    hasattr(object, name):用来检测object(适用于类、文件、模块或对...
    99+
    2023-01-30
    黑魔法
  • Python黑魔法:元类
    Python黑魔法:元类 术语“元编程”指的是程序具有编写或操纵其自身作为它们资料的潜力。Python支持称为元类的类的元编程。 元类是一个深奥的面向对象编程(OOP)概念,隐藏在几乎所有的Python代码之后。无论你是否意识到它的存在,你...
    99+
    2023-01-31
    黑魔法 Python
  • Python定制类你不知道的魔术方法
    目录Python中的魔法方法1.__str__2.__iter__3.__getitem__4.__getattr__5.__call__Python中的魔法方法 方法名说明__st...
    99+
    2024-04-02
  • Python黑魔法远程控制开机的实例
    目录 python黑魔法~只要知道你电脑的ip,远程控制便可开机,嘻嘻《只能用来学习哦~不可恶作剧哈》 def wake_up(request, mac='DC-4A-...
    99+
    2024-04-02
  • 课时47:魔法方法:定制序列
    目录:  一、定制序列   二、课时47课后习题及答案   **************** 一、定制序列 **************** 本节要谈的是定制容器,要想成功的实现容器的定制,便需要先谈一谈协议。协议是什么? 协议(Prot...
    99+
    2023-01-30
    课时 序列 方法
  • 课时44:魔法方法:简单定制
    目录:   一、简单定制   二、课时44课后习题及答案   **************** 一、简单定制 **************** 基本要求:1>> 定制一个计时器的类2>> start和stop方法代...
    99+
    2023-01-30
    课时 简单 方法
  • Python黑魔法之metaclass详情
    目录一、什么是 metaclass二、metaclass 能解决什么问题?三、通过一个实例来理解 metaclass四、Python 底层语言设计层面是如何实现 metaclass ...
    99+
    2024-04-02
  • python黑魔法之参数传递
    我们都听说,python世界里面,万物皆对象。 怎么说万物皆对象呢?最常见的: > class A: pass > a = A() 我们说a是一个对象。 那么既然是万物了,其实A也是对象...
    99+
    2022-06-04
    参数 黑魔法 python
  • python黑魔法之编码转换
    我们在使用其他语言的库做编码转换时,对于无法理解的字符,通常的处理也只有两种(或三种): 抛异常 替换成替代字符 跳过 但是在复杂的现实世界中,由于各种不靠谱,我们处理的文本总会出现那...
    99+
    2022-06-04
    黑魔法 python
  • 掌握 Java Git 黑魔法,解锁版本控制的奥秘
    Git 是一个功能强大的分布式版本控制系统,它可以帮助开发人员跟踪代码更改、协作开发并管理项目历史记录。Java 是目前最流行的编程语言之一,用于构建各种应用程序。将 Git 与 Java 相结合可以显着提高软件开发流程的效率和质量。 G...
    99+
    2024-03-04
    Git、Java、版本控制、黑魔法
  • 揭开 PHP 自动加载的黑魔法:精通加载机制
    PHP 自动加载的原理 PHP 自动加载的工作原理是,当 PHP 执行器遇到未定义的类时,它会触发一个特殊的函数(通常是 __autoload() 或 spl_autoload_register())来加载该类。这个函数会从特定的目录或...
    99+
    2024-03-02
    PHP、自动加载、类加载、命名空间、 composer
  • JavaScript 代理模式:破解黑魔法
    ...
    99+
    2024-04-02
  • Python 隐形大变身:PyInstaller 的黑魔法
    Python 凭借其广泛的库和易于使用的语法,已成为最受开发人员欢迎的编程语言之一。然而,当需要将 Python 应用程序部署为独立的可执行文件时,事情可能会变得复杂。这就是 PyInstaller 发挥作用的地方,它是 Python ...
    99+
    2024-02-15
    Python PyInstaller 打包 可执行文件 GUI
  • python类之特殊属性和魔术方法
    1 总述 属性 含义 _name_ 类,函数,方法等的名字 _module_ 类定义所现在的模块名 _class_ 对象或类所属的类 _bases_ 类的基类的元素,顺序为他们在基类列表中出现的顺序 _doc...
    99+
    2023-01-31
    魔术 属性 方法
  • 魔法标题制造商
    ...
    99+
    2024-04-02
  • 改变 Python 对象规则的黑魔法 Metaclass
    今天小明哥要分享的主题是:改变类定义的神器-metaclass看到标题,你可能会想改变类的定义有什么用呢?什么时候才需要使用metaclass呢?今天我将带大家设计一个简单的orm框架,并简单剖析一下YAML这个序列化工具的原理。Pytho...
    99+
    2023-05-14
    Python Metaclass
  • CMS 的移动魔法:创造定制的移动体验
    ...
    99+
    2024-04-02
  • python中类的魔术方法
    目的:学习python中class的magic methods,提高编程效率。环境:ubuntu 16.4   python 3.5.2在学习class时一定会接触到它的magic methods,比如常用__init__,形式都是前后有双...
    99+
    2023-01-31
    魔术 方法 python
  • Python黑魔法Descriptor描述符的实例解析
    在Python中,访问一个属性的优先级顺序按照如下顺序: 1:类属性 2:数据描述符 3:实例属性 4:非数据描述符 5:__getattr__()方法 这个方法的完整定义如下所示: def __ge...
    99+
    2022-06-04
    实例 黑魔法 Python
  • 魔法标题制造商:吸引读者的魔杖
    魔力揭秘:如何使用魔法标题制造商 使用魔法标题制造商非常简单,只需遵循以下步骤: 输入您的主题或关键字 从生成的大量标题中选择 自定义标题以适应您的需要 成功标题的秘密:了解吸引读者的元素 魔法标题制造商通过以下元素的力量,帮助您打造...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作