广告
返回顶部
首页 > 资讯 > 后端开发 > 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://www.lsjlt.com/news/180227.html(转载时请注明来源链接)

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 定制类和黑魔法
    定制类  反射    反射又称为自省,指的是程序可以访问、检测和修改它本身状态和行为的一种能力。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+
    2022-11-11
  • Python黑魔法远程控制开机的实例
    目录 python黑魔法~只要知道你电脑的ip,远程控制便可开机,嘻嘻《只能用来学习哦~不可恶作剧哈》 def wake_up(request, mac='DC-4A-...
    99+
    2022-11-12
  • 课时47:魔法方法:定制序列
    目录:  一、定制序列   二、课时47课后习题及答案   **************** 一、定制序列 **************** 本节要谈的是定制容器,要想成功的实现容器的定制,便需要先谈一谈协议。协议是什么? 协议(Prot...
    99+
    2023-01-30
    课时 序列 方法
  • 课时44:魔法方法:简单定制
    目录:   一、简单定制   二、课时44课后习题及答案   **************** 一、简单定制 **************** 基本要求:1>> 定制一个计时器的类2>> start和stop方法代...
    99+
    2023-01-30
    课时 简单 方法
  • python类之特殊属性和魔术方法
    1 总述 属性 含义 _name_ 类,函数,方法等的名字 _module_ 类定义所现在的模块名 _class_ 对象或类所属的类 _bases_ 类的基类的元素,顺序为他们在基类列表中出现的顺序 _doc...
    99+
    2023-01-31
    魔术 属性 方法
  • python魔法方法-属性转换和类的表示详解
    类型转换魔法 类型转换魔法其实就是实现了str、int等工厂函数的结果,通常这些函数还有类型转换的功能,下面是一些相关的魔法方法: •__int__(self) •转换成整型,对应i...
    99+
    2022-06-04
    详解 属性 方法
  • C语言修炼之路数据类型悟正法解析存储定风魔下篇
    目录(壹)大端小端藏端倪1.1 什么是大端小端1.2 大端小端模式1)大端模式:2)小端模式:1.3 为什么有大端和小端1.4 如何判断机器的字节序(二) 浮点型在内存中的存储2.1...
    99+
    2022-11-13
  • C语言修炼之路数据类型悟正法 解析存储定风魔上篇
    目录(壹) 数据类型介绍1.1  类型的基本归类(贰)整形在内存中的存储2.1  原码、反码、补码2.2  深入...
    99+
    2022-11-13
  • Python枚举类定义和使用方法
    前言: 一些具有特殊含义的类,其实例化对象的个数往往是固定的,比如用一个类表示月份,则该类的实例对象最多有 12 个;再比如用一个类表示季节,则该类的实例化对象最多有 4 个。 针对...
    99+
    2022-11-11
  • Golang怎么自定义类型和方法集
    这篇文章主要介绍“Golang怎么自定义类型和方法集”,在日常操作中,相信很多人在Golang怎么自定义类型和方法集问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Golang怎么自定义类型和方法集”的疑惑有所...
    99+
    2023-07-05
  • Python中类和对象的绑定及非绑定方法详解
    目录一、绑定方法1 对象的绑定方法2 类的绑定方法二、非绑定方法三、练习1 绑定方法小结2 非绑定方法小结类中定义的方法大致可以分为两类:绑定方法和非绑定方法。其中绑定方法又可以分为...
    99+
    2023-03-03
    Python类 绑定方法 Pytho 对象绑定方法 Python类 对象绑定方法
  • java类的定义和使用方法是什么
    在Java中,类是一种用户自定义的数据类型,用于描述具有相同属性和行为的对象。类的定义包括类名、类的成员变量和方法。类的定义方法如下...
    99+
    2023-09-15
    java
  • Python类的定义和使用方法是什么
    这篇文章主要介绍了Python类的定义和使用方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python类的定义和使用方法是什么文章都会有所收获,下面我们一起来看看吧。一、前言在Python中,类表示具...
    99+
    2023-07-02
  • Python中类和对象的绑定及非绑定方法是什么
    类中定义的方法大致可以分为两类:绑定方法和非绑定方法。其中绑定方法又可以分为绑定到对象的方法和绑定到类的方法。一、绑定方法1 对象的绑定方法在类中没有被任何装饰器修饰的方法就是 绑定到对象的方法,这类方法专门为对象定制。class Pers...
    99+
    2023-05-19
    Python
  • ecshop 二次开发 加入用户定制商品类型的方法
    由于很多用户需要加上商品自定义吃寻大小等 如图 首先在\admin\templates\goods_info.htm里面找到 属性与规格 的位置 发现他调用了{$goods_attr_html}这个页面, 这个函数的定...
    99+
    2022-06-12
    ecshop 商品类型
  • 在Python中定义和使用抽象类的方法
    像java一样python也可以定义一个抽象类。 在讲抽象类之前,先说下抽象方法的实现。 抽象方法是基类中定义的方法,但却没有任何实现。在java中,可以把方法申明成一个接口。而在python中实现一个抽象...
    99+
    2022-06-04
    定义 方法 抽象类
  • CSS的定位机制和position属性的用法
    这篇文章主要讲解了“CSS的定位机制和position属性的用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“CSS的定位机制和position属性的用法”...
    99+
    2022-10-19
  • Golang拾遗之自定义类型和方法集详解
    golang拾遗主要是用来记录一些遗忘了的、平时从没注意过的golang相关知识。 很久没更新了,我们先以一个谜题开头练练手: package main import ( ...
    99+
    2023-02-20
    Golang自定义类型 方法集 Golang自定义类型 Golang 方法集
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作