python 面向对象全面详解
目录
一、对面向对象的理解
1、面向对象的编程---object oriented programming
2、python面向对象的重要术语:
3、函数和面向对象编程的区别
二、封装、继承、多态
1、封装(Encapsulation)
2、继承(Inheritance)
3、多态(Polymorphism)
三、面向对象的各种方法
1、静态方法 (用这个装饰器来表示 @staticmethod )
2、类方法 (用这个装饰器来表示 @classmethod)
3、属性方法 (用这个装饰器表示 @property)
四、高级面向对象
1、成员修饰符
2、特殊成员
3、类与对象
4、异常处理
5、反射/自省
6、单例模式
一、对面向对象的理解
1、面向对象的编程---object oriented programming
简称:OOP,是一种编程的思想。OOP把对象当成一个程序的基本单元,一个对象包含了数据和操作数据的函数。面向对象的出现极大的提高了编程的效率,使其编程的重用性增高。
2、python面向对象的重要术语:
1、多态(polymorphism):一个函数有多种表现形式,调用一个方法有多种形式,但是表现出的方法是不一样的。
2、继承(inheritance)子项继承父项的某些功能,在程序中表现某种联系
3、封装(encapsulation)把需要重用的函数或者功能封装,方便其他程序直接调用
4、类:对具有相同数据或者方法的一组对象的集合
5、对象:对象是一个类的具体事例
6、实例化:是一个对象事例话的实现
7、标识:每个对象的事例都需要一个可以唯一标识这个事例的标记
8、实例属性:一个对象就是一组属性的集合
9、事例方法:所有存取或者更新对象某个实例一条或者多条属性函数的集合。
10、类属性:属于一个类中所有对象的属性,
11、类方法:那些无须特定的对性实例就能够工作的从属于类的函数。
3、函数和面向对象编程的区别
相同点:都是把程序进行封装、方便重复利用,提高效率。
不同点:函数重点是用于整体调用,一般用于一段不可更改的程序。仅仅是解决代码重用性的问题。
而面向对象除了代码重用性。还包括继承、多态等。使用上更加灵活。
二、封装、继承、多态
1、封装(Encapsulation)
封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。
对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过对象直接或者self间接获取被封装的内容。
class Foo:def __init__(self, name, age ,gender):self.name = nameself.age = ageself.gender = genderdef eat(self):print "%s,%s岁,%s,吃奶" %(self.name, self.age, self.gender)def he(self):print "%s,%s岁,%s,喝水" %(self.name, self.age, self.gender)def shui(self):print "%s,%s岁,%s,睡觉" %(self.name, self.age, self.gender)a = Foo('jack', 10, '男')
a.eat()
a.he()
a.shui()b = Foo('rose', 11, '女')
b.eat()
b.he()
b.shui()
2、继承(Inheritance)
继承,面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。
例如:
猫可以:喵喵叫、吃、喝、拉、撒
狗可以:汪汪叫、吃、喝、拉、撒
公共的部分就是 吃、喝、拉、撒
如下实现:
class Animal:def eat(self):print "%s 吃 " %self.namedef drink(self):print "%s 喝 " %self.namedef shit(self):print "%s 拉 " %self.namedef pee(self):print "%s 撒 " %self.nameclass Cat(Animal):def __init__(self, name):self.name = nameself.breed = '猫'def cry(self):print '喵喵叫'class Dog(Animal):def __init__(self, name):self.name = nameself.breed = '狗'def cry(self):print '汪汪叫'# ######### 执行 #########c1 = Cat('猫one')
c1.eat()c2 = Cat('猫two')
c2.drink()d1 = Dog('狗one')
d1.eat()
注意: 关于多继承
- 在Python中,如果父类和子类都重新定义了构造方法init( ),在进行子类实例化的时候,子类的构造方法不会自动调用父类的构造方法,必须在子类中显示调用。
- Python的类可以继承多个类,Java和C#中则只能继承一个类
- Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
- 当类是经典类时,多继承情况下,会按照深度优先方式查找,当类是新式类时,多继承情况下,会按照广度优先方式查找
经典类和新式类,从字面上可以看出一个老一个新,新的必然包含了跟多的功能,也是之后推荐的写法,从写法上区分的话,如果 当前类或者父类继承了object类,那么该类便是新式类,否则便是经典类。
3、多态(Polymorphism)
首先Python不支持多态,也不用支持多态,python是一种多态语言,崇尚鸭子类型。
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”可以这样表述:
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的走和叫方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的走和叫方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。
鸭子类型通常得益于不测试方法和函数中参数的类型,而是依赖文档、清晰的代码和测试来确保正确使用。从静态类型语言转向动态类型语言的用户通常试图添加一些静态的(在运行之前的)类型检查,从而影响了鸭子类型的益处和可伸缩性,并约束了语言的动态特性。
例子:
class A: def prt(self): print "A" class B(A): def prt(self): print "B" class C(A): def prt(self): print "C" class D(A): pass class E: def prt(self): print "E" class F: pass def test(arg): arg.prt() a = A()
b = B()
c = C()
d = D()
e = E()
f = F() test(a)
test(b)
test(c)
test(d)
test(e)
test(f) # 结果
A
B
C
A
E
Traceback (most recent call last): File "/Users/shikefu678/Documents/Aptana Studio 3 Workspace/demo/demo.py", line 33, in <module> test(a),test(b),test(c),test(d),test(e),test(f) File "/Users/shikefu678/Documents/Aptana Studio 3 Workspace/demo/demo.py", line 24, in test arg.prt()
AttributeError: F instance has no attribute 'prt'
没有谁规定test方法是接收的参数是什么类型的。test方法只规定,接收一个参数,调用这个参数的prt方法。在运行的时候如果这个参数有prt方法,python就执行,如果没有,python就报错,因为abcde都有prt方法,而f没有,所以得到了上边得结果,这就是python的运行方式。
三、面向对象的各种方法
1、静态方法 (用这个装饰器来表示 @staticmethod )
意思是把 @staticmethod 下面的函数和所属的类截断了,这个函数就不属于这个类了,没有类的属性了,只不是还是要通过类名的方式调用
看个小例子:
错误示例:class Person(object):def __init__(self, name):self.name = name@staticmethod # 把eat方法变为静态方法def eat(self):print("%s is eating" % self.name)d = Person("xiaoming")
d.eat() ############## 结果:
TypeError: eat() missing 1 required positional argument: 'self'
因为用静态方法把eat这个方法与Person这个类截断了,eat方法就没有了类的属性了,所以获取不到self.name这个变量。
正确示例: class Person(object):def __init__(self, name):self.name = name@staticmethod # 把eat方法变为静态方法def eat(x):print("%s is eating" % x)d = Person("xiaoming")
d.eat("jack") #就把eat方法当作一个独立的函数给他传参就行了
2、类方法 (用这个装饰器来表示 @classmethod)
类方法只能访问类变量,不能访问实例变量
看个例子:
错误示例: class Person(object):def __init__(self, name):self.name = name@classmethod # 把eat方法变为类方法def eat(self):print("%s is eating" % self.name)d = Person("xiaoming")
d.eat() ########### 结果:
AttributeError: type object 'Person' has no attribute 'name'
因为self.name这个变量是实例化这个类传进去的,类方法是不能访问实例变量的,只能访问类里面定义的变量
class Person(object):name="杰克"def __init__(self, name):self.name = name@classmethod # 把eat方法变为类方法def eat(self):print("%s is eating" % self.name)d = Person("xiaoming")
d.eat()
3、属性方法 (用这个装饰器表示 @property)
把一个方法变成一个静态属性,属性就不用加小括号那样的去调用了
看个小例子:
错误示例: class Person(object):def __init__(self, name):self.name = name@property # 把eat方法变为属性方法def eat(self):print("%s is eating" % self.name)d = Person("xiaoming")
d.eat() ##########
结果:
TypeError: 'NoneType' object is not callable
因为eat此时已经变成一个属性了, 不是方法了, 想调用已经不需要加()号了,直接d.eat就可以了
class Person(object):def __init__(self, name):self.name = name@property # 把eat方法变为属性方法def eat(self):print("%s is eating" % self.name)d = Person("xiaoming")
d.eat
四、高级面向对象
1、成员修饰符
python的类中只有私有成员和公有成员两种,不像c++中的类有公有成员(public),私有成员(private)和保护成员(protected).并且python中没有关键字去修饰成员,默认python中所有的成员都是公有成员,但是私有成员是以两个下划线开头的名字标示私有成员,私有成员不允许直接访问,只能通过内部方法去访问,私有成员也不允许被继承。
class a: # 说明父类的私有成员无法在子类中继承def __init__(self):self.ge=123self.__gene=456class b(a):def __init__(self,name):self.name=nameself.__age=18super(b,self).__init__() # 这一行会报错def show(self):print(self.name)print(self.__age)print(self.ge)print(self.__gene) # 这一行也会报错
obj=b("xiaoming")
print(obj.name)
print(obj.ge)
# print(obj.__gene) # 这个也会报错
obj.show()
上面就是类里面的私有成员了。
2、特殊成员
1.__init__
__init__方法可以简单的理解为类的构造方法(实际并不是构造方法,只是在类生成对象之后就会被执行),之前已经在上一篇博客中说明过了。
2.__del__
__del__方法是类中的析构方法,当对象消亡的时候(被解释器的垃圾回收的时候会执行这个方法)这个方法默认是不需要写的,不写的时候,默认是不做任何操作的。因为你不知道对象是在什么时候被垃圾回收掉,所以,除非你确实要在这里面做某些操作,不然不要自定义这个方法。
3.__call__
__call__方法在类的对象被执行的时候(obj()或者 类()())会执行。
4.__int__
__int__方法,在对象被int()包裹的时候会被执行,例如int(obj)如果obj对象没有、__int__方法,那么就会报错。在这个方法中返回的值被传递到int类型中进行转换。
5.__str__
__str__方法和int方法一样,当对象被str(obj)包裹的时候,如果对象中没有这个方法将会报错,如果有这个方法,str()将接收这个方法返回的值在转换成字符串。
6.__add__
__add__方法在两个对象相加的时候,调用第一个对象的__add__方法,将第二个对象传递进来,至于怎么处理以及返回值,那是程序员自定义的,就如下面的例子:
class abc:def __init__(self,age):self.age=agedef __add__(self,obj):return self.age+obj.age
a1=abc(18)
a2=abc(20)
print(a1+a2)
#执行结果:38
7.__dict__
__dict__方法在类里面有,在对象里面也有,这个方法是以字典的形式列出类或对象中的所有成员。就像下面的例子:
class abc:def __init__(self,age):self.age=agedef __add__(self,obj):return self.age+obj.age
a1=abc(18)
print(abc.__dict__)
print(a1.__dict__)
#执行结果:
{'__add__': <function abc.__add__ at 0x0000020666C9E2F0>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'abc' objects>, '__init__': <function abc.__init__ at 0x0000020666C9E268>, '__doc__': None, '__dict__': <attribute '__dict__' of 'abc' objects>}
{'age': 18}
8.__getitem__ __setitem__ __delitem__
__getitem__方法匹配 对象[索引] 这种方式,__setitem__匹配 对象[索引]=value 这种方式,__delitem__匹配 del 对象[索引] 这种方式,例子如下:
class Foo:def __init__(self,name,age):self.name=nameself.age=agedef __getitem__(self, item): # 匹配:对象[item]这种形式return item+10def __setitem__(self, key, value): # 匹配:对象[key]=value这种形式print(key,value)def __delitem__(self, key): # 匹配:del 对象[key]这种形式print(key)li=Foo("alex",18)
print(li[10])
li[10]=100
del li[10]
执行结果:
20
10 100
10
9.__getslice__ __setslice__ __delslice__
这三种方式在python2.7中还存在,用来对对象进行切片的,但是在python3之后,将这些特殊方法给去掉了,统一使用上面的方式对对象进行切片,因此在使用__getitem__ __setitem__ 这两个方法之前要先判断传递进参数的类型是不是slice对象。例子如下:
class Foo:def __init__(self,name,age):self.name=nameself.age=ageself.li=[1,2,3,4,5,6,7]def __getitem__(self, item): # 匹配:对象[item]这种形式if isinstance(item,slice): # 如果是slice对象,返回切片后的结果return self.li[item] # 返回切片结果elif isinstance(item,int): # 如果是整形,说明是索引return item+10def __setitem__(self, key, value): # 匹配:对象[key]=value这种形式print(key,value)def __delitem__(self, key): # 匹配:del 对象[key]这种形式print(key)def __getslice__(self,index1,index2):print(index1,index2)li=Foo("alex",18)
print(li[3:5])
#执行结果:
[4, 5]
10.__iter__
类的对象如果想要变成一个可迭代对象,那么对象中必须要有__iter__方法,并且这个方法返回的是一个迭代器。
for 循环的对象如果是一个可迭代的对象,那么会先执行对象中的__iter__方法,获取到迭代器,然后再执行迭代器中的__next__方法获取数据。如果for循环的是一个迭代器,那么直接执行迭代器中的__next__方法。
class Foo:def __init__(self,name,age):self.name=nameself.age=agedef __iter__(self):return iter([1,2,3,4,5]) # 返回的是一个迭代器
li=Foo("alex",18)# 1.如果类中有__iter__方法,他的对象就是可迭代对象
# 2.对象.__iter()的返回值是一个迭代器
# 3.for循环的如果是迭代器,直接执行.next方法
# 4.for循环的如果是可迭代对象,先执行对象.__iter(),获取迭代器再执行nextfor i in li:print(i)
#执行结果:
1
2
3
4
5
11.isinstance和issubclass
之前讲过isinstance可以判断一个变量是否是某一种数据类型,其实,isinstance不只可以判断数据类型,也可以判断对象是否是这个类的对象或者是这个类的子类的对象,代码如下:
class Foo:def __init__(self,name,age):self.name=nameself.age=age
class Son(Foo):pass
obj=Son("xiaoming",18)
print(isinstance(obj,Foo))
执行结果:True
issubclass用来判断一个类是否是某个类的子类,返回的是一个bool类型数据,代码如下:
class Foo:def __init__(self,name,age):self.name=nameself.age=age
class Son(Foo):pass
obj=Son("xiaoming",18)
print(issubclass(Son,Foo))
执行结果:True
3、类与对象
__new__和__metaclass__
在python中,一切皆对象,我们定义的类其实。。。也是一个对象,那么,类本身是谁的对象呢?在python2.2之前(或者叫经典类中),所有的类,都是class的对象,但是在新式类中,为了将类型(int,str,float等)和类统一,所以,所有的类都是type类型的对象。当然,这个规则可以被修改,在类中有一个属性 __metaclass__ 可以指定当前类该由哪个类进行实例化。而创建对象过程中,其实构造器不是__init__方法,而是__new__方法,这个方法会返回一个对象,这才是对象的构造器。下面是一个解释类实例化对象内部实现过程的代码段:
class Mytype(type):def __init__(self, what, bases=None, dict=None):super(Mytype,self).__init__(what, bases, dict)def __call__(self, *args, **kwargs):obj=self.__new__(self)self.__init__(obj, *args, **kwargs)return obj
class Foo:__metaclass__=Mytypedef __init__(self,name,age):self.name=nameself.age=agedef __new__(cls, *args, **kwargs):return object.__new__(cls)
obj=Foo("xiaoming",18)
print(obj.name,obj.age)
执行结果:xiaoming 18
4、异常处理
python中使用try except finally组合来实现异常扑捉,不像java中是使用try catch finally......其中,except中的Exception是所有异常的父类,下面是一个异常处理的示例:
try:int("aaa") #可能出现异常的代码
except IndexError as e: # 捕捉索引异常的子异常,注意,这里的as e在老版本的py中可以写成,e但是新版本中用as e,",e"未来可能会淘汰print("IndexError:",e)
except ValueError as e: # 捕捉value错误的子异常print("ValueError:",e)
except Exception as e: # 如果上面两个异常没有捕获到,那么使用Exception捕获,Exception能够捕获所有的异常print("Exception:",e)
else: # 如果没有异常发生,执行else中的代码块print("true")
finally: # 不管是否发生异常,在最后都会执行finally中的代码,假如try里面的代码正常执行,先执行else中的代码,再执行finally中的代码print("finally")
执行结果:
ValueError: invalid literal for int() with base 10: 'aaa'
finally
那么既然Exception是所有异常的父类,我们可以自已定义Exception的子类,实现自定义异常处理,下面就是实现例子:
class OldBoyError(Exception): # 自定义错误类型def __init__(self,message):self.message=messagedef __str__(self): # 打印异常的时候会调用对象里面的__str__方法返回一个字符串return self.message
try:raise OldBoyError("我错了...") # raise是主动抛出异常,可以调用自定义的异常抛出异常
except OldBoyError as e:print(e)
执行结果:我错了...
异常处理里面还有一个断言,一般用在判断执行环境上面,只要断言后面的条件不满足,那么就抛出异常,并且后面的代码不执行了。
print(123)
assert 1==2 # 断言,故意抛出异常,做环境监测用,环境监测不通过,报错并结束程序
print("456")
执行结果:assert 1==2 # 断言,故意抛出异常,做环境监测用,环境监测不通过,报错并结束程序
123
AssertionError
5、反射/自省
python中的反射/自省的实现,是通过hasattr、getattr、setattr、delattr四个内置函数实现的,其实这四个内置函数不只可以用在类和对象中,也可以用在模块等其他地方,只是在类和对象中用的很多,所以单独提出来进行解释。
- hasattr(key)返回的是一个bool值,判断某个成员或者属性在不在类或者对象中
- getattr(key,default=xxx)获取类或者对象的成员或属性,如果不存在,则会抛出AttributeError异常,如果定义了default那么当没有属性的时候会返回默认值。
- setattr(key,value)假如有这个属性,那么更新这个属性,如果没有就添加这个属性并赋值value
- delattr(key)删除某个属性
注意,上面的key都是字符串,而不是变量,也就是说可以通过字符串处理类中的成员或者对象中的属性。下面是一个例子代码:
class Foo:def __init__(self,name,age):self.name=nameself.age=agedef show(self):return self.name,self.age
obj=Foo("xiaoming",18)
print(getattr(obj,"name"))
setattr(obj,"k1","v1")
print(obj.k1)
print(hasattr(obj,"k1"))
delattr(obj,"k1")
show_fun=getattr(obj,"show")
print(show_fun())
执行结果:
xiaoming
v1
True
('xiaoming', 18)
反射/自省能够直接访问以及修改运行中的类和对象的成员和属性,这是一个很强大的功能,并且并不像java中效率很低,所以用的很多。
下面是一个反射/自省用在模块级别的例子:
import s2
operation=input("请输入URL:")
if operation in s2.__dict__:getattr(s2,operation)()
else:print("404")#模块s2中的代码:
def f1():print("首页")
def f2():print("新闻")
def f3():print("精选")
执行结果:
请输入URL:f1
首页
6、单例模式
这里介绍一个设计模式,设计模式在程序员写了两三年代码的时候,到一定境界了,才会考虑到设计模式对于程序带来的好处,从而使用各种设计模式,这里只是简单的介绍一个简单的设计模式:单例模式。在面向对象中的单例模式就是一个类只有一个对象,所有的操作都通过这个对象来完成,这就是面向对象中的单例模式,下面是实现代码:
class Foo: # 单例模式__v=None@classmethoddef ge_instance(cls):if cls.__v:return cls.__velse:cls.__v=Foo()return cls.__v
obj1=Foo.ge_instance()
print(obj1)
obj2=Foo.ge_instance()
print(obj2)
obj3=Foo.ge_instance()
print(obj3)
执行结果:
<__main__.Foo object at 0x000001D2ABA01860>
<__main__.Foo object at 0x000001D2ABA01860>
<__main__.Foo object at 0x000001D2ABA01860>
可以看到,三个对象的内存地址都是一样的,其实,这三个变量中存储的都是同一个对象的内存地址,这样有什么好处呢?能够节省资源,就比如在数据库连接池的时候就可以使用单例模式,只创建一个类的对象供其他程序调用,还有在web服务中接收请求也可以使用单例模式来实现,节省资源。
勇气通往天堂,怯懦通往地狱。
python 面向对象全面详解相关推荐
- Python面向对象知识点详解(含__init__、__add__、__str__、issubclass()、isinstance()等方法的使用)
Python面向对象 创建类 类属性与方法 `__init__()` 类的构造函数(初始化方法) 类的继承 方法重写 基础重载方法 `__str__( self )`的使用 运算符重载 `__add_ ...
- python是基于什么原理_Python基于class()实现面向对象原理详解
首先,类是一个集合,包含了数据,操作描述的一个抽象集合 你可以首先只把类当做一个容器来使用 class Cycle: def __init__(self,r): self.pi=3.14 self.r ...
- Python开发技术详解PDF
Python开发技术详解(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1F5J9mFfHKgwhkC5KuPd0Pw 提取码:xxy3 复制这段内容后打开百度网盘手 ...
- Python基础知识详解 从入门到精通(八)魔法方法
目录 Python基础知识详解 从入门到精通(八)魔法方法 什么是魔法方法 基础魔法方法(较为常用) 比较操作符 算数运算符 反运算(类似于运算方法) 增量赋值运算 一元操作符 类型转换 上下文管理( ...
- Python开发技术详解
Python开发技术详解 下载地址 https://pan.baidu.com/s/1KTrk3B1sajMiPIoo3-Rhuw 扫码下面二维码关注公众号回复 100089获取分享码 本书目录结构如 ...
- python开发技术详解pdf下载_python开发技术详解附源码-python开发技术详解电子书pdf下载高清去水印版-精品下载...
Python开发技术详解适合Python爱好者.大中专院校的学生.社会培训班的学生以及用Python语言进行系统管理.GUI开发.Web开发.数据库编程.网络编程的人员使用. 内容提要 Python是 ...
- 站长在线Python教程:Python中类定义详解
导读:欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<Python中类定义详解>. 我们在上一节内容<Python中面向对象相关概述详解>中学习过,类是具有相同 ...
- python20191031_20191031:Python取反运算详解
20191031:Python取反运算详解 取反运算:~3 == 4 1.对于数字 3 =======>转换为二进制表示为011 2.对011取反为100 3.为什么表示-4 a.计算机用补码表 ...
- Python字符编码详解
Python字符编码详解 转自http://www.cnblogs.com/huxi/archive/2010/12/05/1897271.html Python字符编码详解 本文简单介绍了各种常用的 ...
- python的执行过程_在交互式环境中执行Python程序过程详解
前言 相信接触过Python的伙伴们都知道运行Python脚本程序的方式有多种,目前主要的方式有:交互式环境运行.命令行窗口运行.开发工具上运行等,其中在不同的操作平台上还互不相同.今天,小编讲些Py ...
最新文章
- UNIX/Linux基本命令大全
- 好程序员大数据培训技术分享:Hadoop集群同步
- 某云数据中心网络解决方案(分享二十一)
- 【设计模式】-写在前面
- 计算机风冷散热系统的原理,显卡“发烧”的原因_显卡散热原理
- idea 编译显示source1.3不支持泛型(请使用source5或更高版本)
- vim中taglist无法显示问题
- LINUX 对引导加密
- 【C++深度剖析教程17】逻辑操作符的陷阱
- Microsoft Sql Server 2008 R2 Express 下载地址推荐
- 小米音箱蓝牙连不上_小米互联网音箱蓝牙怎么连接?方法如下
- si4463的寄存器使用说明
- 查看虚拟机ip地址的方法
- 商品订单(增删改查):新增订单;批量删除,发货;模糊查询,下拉菜单内容过滤(含时间);全选反选,列名排序
- 瀑布流布局浅析+常用插件介绍(转改编)
- 基于MM32与M26物联网入门:远程呼叫及开锁
- wifi服务器延迟高,网络延时高(网络延迟高怎么办(家里WIFI延迟高,教你几招搞定网络延迟))...
- 阿里云华北1235、华东1、华东2和华南1分别对应哪些城市?地域节点物理数据中心在哪?...
- 表达矩阵melt之后 画图 reshape gaochao ards 1: Unknown or uninitialised column: `p`. 2: Computation failed i
- C# 串口接收含有asic2=0x3f时发生的故障
热门文章
- 锁定计算机怎么设密码忘记了怎么办,如何设置笔记本电脑指纹密码忘了怎么办...
- Java实现:四六级真题批量PDF文件英文单词词频分析、排序
- ElasticSearch教程——数据一致性
- 移动硬盘使用时间、读写速度和坏道查询
- 从学生到职场,这位百万爬虫博主都经历了什么?
- 基本的ps快捷键(图文)
- b和kb的换算_kb和b换算(b kb mb换算)
- PayPal提现到美国账户收35美元怎么办?最新3种解决办法!
- paypal php 方式,如何使用PHP向paypal汇款
- AVC/HEVC/VVC/AV1 块划分、帧内预测过程及预测模式编码