当前位置: 首页 > 编程日记 > 正文

Python基础20-面向对象:静态、组合、继承与派生、多态、封装、反射、内置attr方法等

目录

静态

静态属性@property

类方法@classmethod

静态方法@staticmethod

组合

继承与派生

继承与派生

继承顺序

在子类中调用父类方法与super

多态

封装

反射

模块的动态导入

内置的attr方法

带双下户线的attr方法__setattr__、__getattr__、__delattr__

__getattr__方法的牛逼用法

继承方式完成包装


静态

静态属性@property

以类Room为例,Room类里面存储了width、length、height属性,面积、体积都是通过这些属性计算出来的,没有必要再存一份面积、体积。使用装饰器@property可以把有返回值的方法变成属性一样,这样减少了冗余,对调用者来说就像直接访问属性一样方便。这就是静态属性。

class Room:def __init__(self, name, owner, width, length, height):self.name = nameself.owner = ownerself.width = widthself.length = lengthself.height = heightpass@propertydef area(self):"""计算面积:return: 面积"""return self.width * self.lengthpass@propertydef volume(self):"""计算体积:return: 体积"""return self.width * self.length * self.heightpasspass"""
静态属性类里面存储了width、length、height属性
面积、体积都是通过这些属性计算出来的,没有必要再存一份面积、体积
使用装饰器@property可以把有返回值的方法变成属性一样,这样减少了冗余
对调用者来说就像直接访问属性一样方便
"""
r1 = Room('五路居', 'Kevin', 18, 15, 3)
r2 = Room('回龙观', 'Alice', 15, 20, 3)
print(r1.area)
print(r2.area)
print(r1.volume)
print(r2.volume)
# Kevin 住的 五路居 总面积是 270平米 体积是 810立方米
# Alice 住的 回龙观 总面积是 300平米 体积是 900立方米

类方法@classmethod

我们有时候访问类属性,不需要访问对象,而所有带self参数的方法都要求先有对象实例,这就产生了矛盾。那么,就得用classmethod装饰器,被classmethod装饰的方法都自带cls参数,直接使用类名调用类方法,访问类属性。

class Room:tag = 1def __init__(self, name, owner, width, length, height):self.name = nameself.owner = ownerself.width = widthself.length = lengthself.height = heightpass@propertydef area(self):"""计算面积:return: 面积"""return self.width * self.lengthpass@propertydef volume(self):"""计算体积:return: 体积"""return self.width * self.length * self.heightpass@classmethoddef tell_info(cls, x):print('类方法访问类属性tag--->', cls.tag, x)passpass"""
类方法我们有时候访问类属性,不需要访问对象,而所有带self参数的方法都要求先有对象实例,这就产生了矛盾。
那么,就得用classmethod装饰器,被classmethod装饰的方法都自带cls参数,直接使用类名调用类方法,访问类属性。
"""
Room.tell_info('入参x')
# 类方法访问类属性tag---> 1 入参x

静态方法@staticmethod

静态方法本身,既和类无关,也个对象实例无关。类可以调用静态方法,对象实例也可以调用静态方法。按照规范应该由类来直接调用。静态方法是类的工具包。比如Java里面的Math类就定义了log,exp等静态方法。这些方法和数字类、数字对象都无关,但是可以做运算。

class Room:tag = 1def __init__(self, name, owner, width, length, height):self.name = nameself.owner = ownerself.width = widthself.length = lengthself.height = heightpass@propertydef area(self):"""计算面积:return: 面积"""return self.width * self.lengthpass@propertydef volume(self):"""计算体积:return: 体积"""return self.width * self.length * self.heightpass@classmethoddef tell_info(cls, x):print('类方法访问类属性tag--->', cls.tag, x)pass@staticmethoddef bathroom(p):print('%s 在房间里洗澡' % p)passpass"""
静态方法静态方法本身,既和类无关,也个对象实例无关。
类可以调用静态方法,对象实例也可以调用静态方法。按照规范应该由类来直接调用。
静态方法是类的工具包。
比如Java里面的Math类就定义了log,exp等静态方法。
这些方法和数字类、数字对象都无关,但是可以做运算。
"""
Room.bathroom('Kevin')
# Kevin 在房间里洗澡

组合

类的对象本身也可以作为另一个类的属性。比如点这个类的对象可以作为圆的圆心。

class Point:def __init__(self, x, y):self.x = xself.y = ypasspassclass Circle:def __init__(self, center, radius):self.center = center  # 圆心self.radius = radius  # 半径passpassp1 = Point(2, 2)
c1 = Circle(p1, 3)
print(c1.__dict__)
# {'center': <__main__.Point object at 0x00000000026C9BA8>, 'radius': 3}# 圆的位置的x坐标
print(c1.center.x)

继承与派生

继承与派生

当一个类是另一个类的时候,就存在着继承关系,我们把是另一个类的共同的属性提取出来,做成父类,一个类从这个父类继承。比如,猫、狗是动物,他们都有毛色、品种,都会吃、叫,那么父类就是动物,猫、狗从动物继承。继承操作应尽量定义一个接口父类,子类继承接口父类,并在子类中实现继承下来的接口。这就类似于Java中的abstract class或interface。

怎么实现接口父类呢?那么就是abc模块(Abstract Base Class)。接口父类里面加上metaclass=abc.ABCmeta,这样定义的父类才能使子类必须实现父类接口,否则子类在实例化时会报错。

当一个类从父类继承以后,还可以自己新增更多只属于自己的属性,这就是派生。猫、狗都从动物继承,猫还可以派生九条命数据属性和上树方法,狗还可以派生出狗刨方法。

import abcclass Animal(metaclass=abc.ABCMeta):@abc.abstractmethoddef bark(self):pass@abc.abstractmethoddef eat_food(self, food):passpassclass Cat(Animal):def bark(self):print('喵喵!')passdef eat_food(self, food):print('猫吃%s' % food)passpassclass Dog(Animal):def bark(self):print('汪汪!')passdef eat_food(self, food):print('狗吃%s' % food)passpassc1 = Cat()
c1.bark()
c1.eat_food('鱼')
# 喵喵!
# 猫吃鱼d1 = Dog()
d1.bark()
d1.eat_food('骨头')
# 汪汪!
# 狗吃骨头

继承顺序

Java只支持单继承,一个类只有一个父类,但是可以实现多个interface。Python不同,Python支持多继承,可以有多个父类,那么就涉及到一个继承顺序的问题。假设这样的场景,F→D→B→A,F→E→C→A。也就是F继承D、E,D继承B继承A,E继承C继承A。继承顺序来自于类的MRO列表(Method Resolve Order 方法解析顺序列表),我们可以通过__mro__属性来看到这个顺序。

Python调用方法的时候,先从子类自己找,如果找不到再按照类的MRO列表顺序找,如果对于继承的方法有两个符合要求的实现,那么调用第一个父类中的实现。

class A:def test(self):print('A')passclass B(A):def test(self):print('B')passclass C(A):def test(self):print('C')passclass D(B):def test(self):print('D')passclass E(C):def test(self):print('E')passclass F(E, D):def test(self):print('F')passf1 = F()
f1.test()  # F
print(F.__mro__)
# (<class '__main__.F'>, 先从自己找
# <class '__main__.E'>, 然后从第一个父类找
# <class '__main__.C'>, 
# <class '__main__.D'>, 
# <class '__main__.B'>, 
# <class '__main__.A'>, 直至找到根基类
# <class 'object'>)以及object

同理,对于数据属性也是一样的顺序。

class A:def __init__(self, x=10):self.x = xpasspassclass B:def __init__(self, x=17):self.x = xpasspassclass C(B, A):def __init__(self):super().__init__()passdef show_info(self):print(self.x)passpassc = C()
c.show_info()  # 17

在子类中调用父类方法与super

关于这一部分,我们先看看文档里面怎么写的。我们可以直接调用super()来得到父类,然后调用父类方法。或者我们可以用super(__class__,<first argument>),也就是super(子类名,第一个参数self)。

    def __init__(self, type1=None, type2=None): # known special case of super.__init__"""super() -> same as super(__class__, <first argument>)super(type) -> unbound super objectsuper(type, obj) -> bound super object; requires isinstance(obj, type)super(type, type2) -> bound super object; requires issubclass(type2, type)Typical use to call a cooperative superclass method:class C(B):def meth(self, arg):super().meth(arg)This works for class methods too:class C(B):@classmethoddef cmeth(cls, arg):super().cmeth(arg)# (copied from class doc)"""pass

举个栗子。

class Vehicle:def __init__(self, name, speed, load):self.name = nameself.speed = speedself.load = loadpassdef run(self):print('启动了!')passdef show_info(self):print(self.name, self.speed, self.load)passpassclass Subway(Vehicle):def __init__(self, name, speed, load, line):super(Subway, self).__init__(name, speed, load)self.line = linepassdef run(self):super().run()print('%s %s 线,以 %s 速度前进。' % (self.name, self.line, str(self.speed)))passdef show_info(self):print(self.name, self.speed, self.load, self.line)passpassline13 = Subway('北京地铁', '60km/h', 1200, '13')
# 北京地铁 60km/h 1200 13
line13.show_info()
# 启动了!
line13.run()
# 北京地铁 13 线,以 60km/h 速度前进。

多态

多态是一种运行时动态绑定的概念。多态与集成是伴随出现的,两者不能割裂开来。

回忆一下Java,方法形参为abstract class或者interface,调用时传入的实参是实现了抽象类的子类对象或者实现了接口的类的对象。这样在调用的时候,动态调用的是实现以后的方法。

在Python中也有多态的概念,也是运行时动态绑定的概念。回忆一下len方法,不管传入的是str、dict、list、tuple、set还是其他什么类型,都可以获取到长度。实际上,这些对象都实现了__len__方法,在调用len函数的时候,都动态执行了各自对象实现的__len__方法。不同的对象,调用相同的方法,每个对象方法的实现不一样实现不同的功能,这就是多态。

我们回到猫、狗的例子。看一下多态polymorphism是怎么实现的。

import abcclass Animal(metaclass=abc.ABCMeta):@abc.abstractmethoddef bark(self):pass@abc.abstractmethoddef eat_food(self, food):passpassclass Cat(Animal):def bark(self):print('喵喵!')passdef eat_food(self, food):print('猫吃%s' % food)passpassclass Dog(Animal):def bark(self):print('汪汪!')passdef eat_food(self, food):print('狗吃%s' % food)passpassdef feed_pet(obj, food):"""喂宠物吃东西:param obj::param food::return:"""obj.eat_food(food)passdef play_with_pet(obj):"""和宠物玩,宠物会叫:param obj::return:"""obj.bark()passif __name__ == '__main__':c1 = Cat()d1 = Dog()feed_pet(c1, '鱼')  # 猫吃鱼feed_pet(d1, '骨头')  # 狗吃骨头play_with_pet(c1)  # 喵喵!play_with_pet(d1)  # 汪汪!pass

封装

封装就是隐藏内部的实现逻辑以及不允许用户直接访问的数据。这样有利于内部逻辑的实现,也防止了用户意外修改本不应该修改的数据。

回忆一下Java是怎么实现封装的?是通过关键字private、[不加关键字default]、protected和public四种访问权限关键字来实现封装的。每种修饰都对应着私有、包、子类、公有的不同访问权限。

Java的封装实现

私有权限

只有类自己可以访问到

包权限

同一个包下的其他类可以访问

子类权限

继承这个类的子类可以访问

子类和父类可能不在一个包

公有权限

任何地方都可以访问

private
【不加关键字default】
protected
public

那么Python怎么实现封装的呢?比较绕。我们注意一下Python约定的规则,一个、两个下划线开头表示外部不应直接访问的属性。

# polymorphism.py
import abcclass Animal(metaclass=abc.ABCMeta):@abc.abstractmethoddef bark(self):pass@abc.abstractmethoddef eat_food(self, food):passpassclass Cat(Animal):fur_color = 'blue'_fur_color = '_blue'__fur_color = '__blue'def bark(self):print('喵喵!')passdef eat_food(self, food):print('猫吃%s' % food)passpassclass Dog(Animal):def bark(self):print('汪汪!')passdef eat_food(self, food):print('狗吃%s' % food)passpassdef feed_pet(obj, food):"""喂宠物吃东西:param obj::param food::return:"""obj.eat_food(food)passdef play_with_pet(obj):"""和宠物玩,宠物会叫:param obj::return:"""obj.bark()passif __name__ == '__main__':c1 = Cat()d1 = Dog()feed_pet(c1, '鱼')  # 猫吃鱼feed_pet(d1, '骨头')  # 狗吃骨头play_with_pet(c1)  # 喵喵!play_with_pet(d1)  # 汪汪!pass

调用的代码,这里要讲述的是Python里面一个、两个下划线定义的属性只是约定,但并不是真正意义上的封装。一个下划线开头的属性可以直接被访问到。两个下划线开头的属性被重新命名了,命名为_类名__属性,比如__fur_color就被转换为_Cat__fur_color,这个属性可以被直接访问到。

结论是,Python中并不像Java那样严格定义了封装,因为封装不只是把属性隐藏,被隐藏的那部分怎么被外部访问到也是封装要考虑的内容。因此Python中并没有严格定义了访问权限的封装。

# packaging.py
from polymorphism import *c1 = Cat()
d1 = Dog()
play_with_pet(c1)
play_with_pet(d1)# 注意Python不会真的封装
# 一个、两个下划线只是一种约定
# 注意Cat的__dict__里面两个下划线的属性__fur_color被重命名成_Cat__fur_color
print(c1.fur_color)  # blue
print(c1._fur_color)  # _blue
print(c1._Cat__fur_color)  # __blue
print(Cat.__dict__)
# {'__module__': 'polymorphism',
# 'fur_color': 'blue',
# '_fur_color': '_blue',
# '_Cat__fur_color': '__blue',
# 'bark': <function Cat.bark at 0x0000000003BAA8C8>,
# 'eat_food': <function Cat.eat_food at 0x0000000003BAA950>,
# '__doc__': None,
# '__abstractmethods__': frozenset(),
# '_abc_registry': <_weakrefset.WeakSet object at 0x0000000003B8D940>,
# '_abc_cache': <_weakrefset.WeakSet object at 0x0000000003B8D978>,
# '_abc_negative_cache': <_weakrefset.WeakSet object at 0x0000000003B8D9B0>,
# '_abc_negative_cache_version': 47}

反射

先介绍一下hasattr、getattr、setattr、delattr四个内置函数,分别用于查、取、增改、删除对象的属性。这四个方法都利用了反射机制,在运行时要对象实例自己清楚自己有什么、可以干什么。

先来看hasattr和getattr。

class FtpClient:def __init__(self, addr):print('ftp连接中……')self.addr = addrpass# def put(self):#     print('文件上传中……')#     passpassif __name__ == '__main__':fc = FtpClient('1.1.1.1')if hasattr(fc, 'put'):# hasattr传入对象和字符串,看是否有字符串名字的属性,返回布尔值# getattr传入对象和字符串,获取属性func_put = getattr(fc, 'put')func_put()else:print('put功能尚未完成,请继续其他工作!')pass
# ftp连接中……
# put功能尚未完成,请继续其他工作!#========== 或者用另一种实现,利用getattr的default参数 ==========if __name__ == '__main__':fc = FtpClient('1.1.1.1')func_put = getattr(fc, 'put', lambda x=None: print('put功能尚未完成,请继续其他工作!'))func_put()pass

至于setattr和delattr。接上面FtpClient的代码可以动态增加减少属性。

if __name__ == '__main__':def func_get():print('get from ftp')passsetattr(FtpClient, 'get', func_get)print(FtpClient.__dict__)# {'__module__': '__main__', # '__init__': <function FtpClient.__init__ at 0x00000000028B50D0>, # '__dict__': <attribute '__dict__' of 'FtpClient' objects>, # '__weakref__': <attribute '__weakref__' of 'FtpClient' objects>, # '__doc__': None, # 'get': <function func_get at 0x0000000001D11EA0>}delattr(FtpClient, 'get')print(FtpClient.__dict__)# {'__module__': '__main__', # '__init__': <function FtpClient.__init__ at 0x00000000028B50D0>, # '__dict__': <attribute '__dict__' of 'FtpClient' objects>,# '__weakref__': <attribute '__weakref__' of 'FtpClient' objects>, # '__doc__': None}pass

模块的动态导入

如果用from …… import *的方式,一个、两个下划线开头的函数就不能被直接导入。需要直接指定函数的名称才能被导入使用。

from m1.t import test1, _test2, __test3test1()  # from test1
_test2()  # from test2
__test3()  # from test3

用__import__函数可以以字符串的形式导入模块。不管字符串里面写了多少层,导入的只是字符串中所表示的最顶层的模块。而且这种导入,用“点”的方式调用一个、另两个下划线开头的方法可以直接调用。

module_t = __import__('m1.t')
# 虽然写了m1.t,但是只导入了m1模块
# 调用还是要m1.t取调用
module_t.t.test1()  # from test1
module_t.t._test2()  # from test2
module_t.t.__test3()  # from test3# 只能拿到顶级的模块名m1
print(module_t) # <module 'm1' from 'C:\\dev\\day26_object_oriented\\m1\\__init__.py'>

使用importlib模块也可以以字符串的形式来导入模块,不管字符串里面写了多少层,导入的都是最后面表示的那一层。比如,导入的的是m1.t,那么拿到的就是m1.t模块。

import importlibmt = importlib.import_module('m1.t')
mt.test1()  # from test1
mt._test2()  # from test2
mt.__test3()  # from test3# 可以拿到字符串指定的模块m1.t,不管多少层
print(mt)  # <module 'm1.t' from 'C:\\dev\\day26_object_oriented\\m1\\t.py'>

内置的attr方法

带双下划线的attr方法__setattr__、__getattr__、__delattr__

给属性做赋值操作(修改、增加)时,__setattr__方法被调用。

访问不存在的属性时,__getattr__方法被调用。

删除属性时,__delattr__方法被调用。

这三个方法是Python内置的,不定义也有。我们定义就相当于重新定义了这三个方法。使用者三个方法时应当注意被触发的条件。

__setattr__方法的实现不能直接用self.attr=value的直接赋值方法,因为赋值操作会触发__setattr__被调用,陷入无限递归,正确的做法是使用__dict__的字典操作,用键值对来赋值。这个看起来没什么用,事实上确实没什么用。__setattr__不常用。

__delattr__方法的实现不能用del self.item的直接删除方法,因为删除操作会触发__delattr__,陷入无限递归,正确的做法是使用__dict__的字典操作,用字典的pop方法来删除。这个看起来也没什么用,事实上确实也没什么用。__delattr__不常用。

__getattr__也可以用类似机制重新实现。

class Foo:x = 10def __init__(self, y=27):self.y = ypassdef __getattr__(self, item):print('__getattr__被调用')# 用来在被访问没有的属性时给出回应passdef __setattr__(self, key, value):print('__setattr__被调用')# 注意,不能直接赋值,否则会触发__setattr__陷入无限递归,报错# 使用__dict__做字典操作赋值self.__dict__[key] = valuepassdef __delattr__(self, item):print('__delattr__被调用')# 注意,不能直接del删除,否则会触发__delattr__陷入无限递归,报错self.__dict__.pop(item)passpassprint()
# 当有属性赋值操作的时候,__setattr__被调用
f = Foo()
# __setattr__被调用
f.y = 8
# __setattr__被调用
f.z = 19
# __setattr__被调用# 当访问对象存在的属性时,不会调用__getattr__
print(f.x)
# 10# 当访问对象不存在的属性时,__getattr__被调用
print(f.w)
# __getattr__被调用
# None# 当删除属性时,__delattr__被调用
del f.y
# __delattr__被调用

__getattr__方法的牛逼用法

通过对__getattr__方法重写,在不实现类所有功能的情况下,却能直接调用其组合内容的所有方法。

class FileHandler:def __init__(self, filename, mode='r', encoding='utf-8'):self.file = open(filename, mode=mode, encoding=encoding)self.mode = modeself.encoding = encodingpassdef __getattr__(self, item):# 触发这个方法以后用getattr函数返回self.file对应的属性# 从而实现了将file的属性全部放给用户调用return getattr(self.file, item)passpassf = FileHandler('file', 'w+')
# 以下三个方法都没有在FileHandler里面实现
# 访问不存在的属性,触发了__getattr__方法
f.write('This is a test line.')
f.seek(0)
print(f.read())

继承方式完成包装

我们的list、tuple、dict、set等内置的数据类型并不会对数据类型做限制,一个列表里面既可以放str,也可以放tuple,还可以放数字。但是,有时候我们需要列表里面只能放入一种数据类型。这个时候,我们就要从这些内置的数据类型继承,他们也是类也可以被继承和派生。

我们就包装元素只能是str的list。本例只重写了append和insert方法,说明用法,并没有重写如__init__、extend等方法,所以并不是真正意义上的“元素只能是str”的list。

class StrList(list):"""字符串列表,元素只能是字符串"""def append(self, p_object):if type(p_object) is str:super().append(p_object)passdef insert(self, index, p_object):if type(p_object) is str:super().insert(index, p_object)passpassstr_list = StrList('mysql')
print(str_list)
# ['m', 'y', 's', 'q', 'l']str_list.append(123)
str_list.append('abc')
print(str_list)
# ['m', 'y', 's', 'q', 'l', 'abc']
# 123是数字没有别加进来str_list.insert(3, 'hello')
str_list.insert(3, (1, 2, 3,))
print(str_list)
# ['m', 'y', 's', 'hello', 'q', 'l', 'abc']
# (1,2,3,)是tuple没有被加进来

相关文章:

C++ primer 第三章笔记

chapter 3 字符串,向量,数组 # 命名空间的using声明 头文件不应包含using声明; 注:using namespace std; #标准库类型string 1.string 表示可变长的字符序列; 2.#include<string> 3.字符串字面量 与 string 是不同类型; 4.cctype头文件种定义了一组标准库函数(改变某个字…

街篮最新服务器,《街篮》全新两组服务器开启 与你一起迎新年!

2016还剩下几个小时&#xff0c;2017即将到来。为了庆祝新的一年到来&#xff0c;《街篮》两组全新的服务器“闻鸡起舞”与“金鸡独立”正式与大家见面&#xff01;本次新服务器将在官服和混服同时开启&#xff0c;其中“闻鸡起舞”属于G系的新服务器&#xff0c;而“金鸡独立”…

Android架构篇-4 架构模式MVVM

Android架构篇-4 架构模式MVVM MVVM原理 #mermaid-svg-CJmTYPxP5GkKNMic .label{font-family:trebuchet ms, verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-CJmTYPxP5GkKNMic .label text{fill:#333}#mermaid-svg-CJmTYPxP5GkKNM…

jupyter安装与初探

安装jupyter jupyterlab和jupyter notebook的关系暂时没有搞清楚。先都安装了吧&#xff0c;用用再说。 选择国内镜像&#xff0c;避免万里长城的干扰。 pip install jupyterlab -i http://uni.mirrors.163.com --trust-host uni.mirrors.163.com pip install jupyter noteb…

android专题-数据库Room

android专题-数据库Room Room介绍 room是Google官方推荐的ORM数据库框架&#xff0c;抽象出sqlite访问的数据库。 包含三大组件&#xff1a; Entity 定义 表结构&#xff0c;每个entity类对一个表&#xff0c;默认会把entity类所有字段都创建为表字段Dao 定义entity类的CRUD…

CentOS 6.7快速搭建lamp环境

安装前要关闭防火墙&#xff0c;防止外网不能访问&#xff0c;这一点很重要&#xff0c;要不然外网访问不了&#xff1b; ①关闭防火墙&#xff1a;service iptables stop ②永久关闭防火墙&#xff1a;chkconfig iptables off ③查看防火墙状态&#xff1a;service iptables …

1005 生日礼物

1005 生日礼物 时间限制: 1 s空间限制: 128000 KB题目等级 : 黄金 Gold题解题目描述 Description9月12日是小松的朋友小寒的生日。小松知道小寒特别喜欢蝴蝶&#xff0c;所以决定折蝴蝶作为给小寒的生日礼物。他来到了PK大学最大的一家地下超市&#xff0c;在超市里&#xff0c…

css多行省略号兼容ie,css超出2行部分省略号……,兼容ie

html>Page Title.wrap {height: 40px;line-height: 20px;overflow: hidden;}.wrap .text {float: right;margin-left: -5px;width: 100%;word-break: break-all;}.wrap::before {float: left;width: 5px;content: ‘‘;height: 40px;}.text {position: relative;line-height…

机器学习01-定义、线性回归、梯度下降

目录 一、定义 What is Machine Learning 二、建模 Model Representation 三、一元线性回归 Linear Regression with One Variable 3.1 一元线性归回的符号约定 Notation 3.2 一元线性回归 Linear Regression with One Variable 3.3 代价函数 Cost Function 3.4 梯度下降…

android专题-蓝牙扫描、连接、读写

android专题-蓝牙扫描、连接、读写 概念 外围设备 可以被其他蓝牙设备连接的外部蓝牙设备&#xff0c;不断广播自身的蓝牙名及其数据&#xff0c;如小米手环、共享单车、蓝牙体重秤 中央设备 可以搜索并连接周边的外围设备&#xff0c;并与之进行数据读写通讯&#xff0c;…

2 并发编程--开启进程的两种方式

multiprocessing 英 /mʌltɪprəʊsesɪŋ/ n. [计][通信] 多重处理 1、multiprocessing 模块介绍 python中的多线程无法利用多核优势&#xff0c;如果想要充分地使用多核CPU的资源&#xff08;os.cpu\_count\(\)查看&#xff09;&#xff0c;在python中大部分情况需要使用多…

POJ 2112 Optimal Milking(二分+最大流)

POJ 2112 Optimal Milking 题目链接 题意&#xff1a;给定一些机器和奶牛&#xff0c;在给定距离矩阵&#xff0c;&#xff08;不在对角线上为0的值代表不可达&#xff09;&#xff0c;每一个机器能容纳m个奶牛。问全部奶牛都能挤上奶&#xff0c;那么走的距离最大的奶牛的最小…

ajax的loading方法,Ajax加载中显示loading的方法

使用ajaxStart方法定义一个全局的“加载中。。。”提示$(function(){$("#loading").ajaxStart(function(){$(this).html.("");});$("#loading").ajaxSuccess(function(){$(this).html.("");// $(this).empty(); // 或者直接清除});});…

机器学习02-分类、逻辑回归

目录 一、分类问题 Classification 二、分类问题的估值 Hypothesis Representation 三、分类问题的决策边界 Decision Boundary 四、分类问题的代价函数 Cost Function 五、简化的代价函数与梯度下降Simplified Cost Function & Gradient Descent 5.1 简化代价函数 …

python绘制盖尔圆并做特征值的隔离

本程序并非智能到直接运行隔离出所有特征值&#xff0c;而是需要高抬贵手&#xff0c;手动调节变换矩阵D的参数&#xff0c;以实现特征值的隔离。若期待直接找到能特征值隔离的D矩阵参数变化范围&#xff0c;怕足下要失望了&#xff0c;鄙人暂没有做到那一步&#xff0c;一是因…

mysql 电商项目(一)

mysql 电商项目 - MySQL数据库开发规范 1、数据库基本设计规范  2、索引设计规范 3、数据库字段设计规范 4、数据库SQL开发规范 5、数据库操作行为规范 转载于:https://www.cnblogs.com/Eric15/articles/9719814.html

Android专题-常用第三方框架

Android专题-常用第三方框架 HTTP网络请求 带*号的是个人推荐比较好用的 HTTP网络请求 okhttp * :https://github.com/square/okhttp retrofit:https://github.com/square/retrofit Volley:https://github.com/google/volley Android Async HTTP:https://github.com/andr…

WPF显示经常使用的几个显示文字控件TextBox, TextBlock, Lable

WPF显示经常使用的几个显示文字控件TextBox&#xff0c; TextBlock&#xff0c; Lable TextBox&#xff0c; TextBlock。 Lable 当中TextBox 和Lable均继承了Control类 能够对其进行模板编辑。而TextBlock没有继承Control所以不能对其进行模板编辑 我的程序中须要做一个二级菜单…

机器学习03-神经网络

目录 一、非线性估值Non-Linear Hypothesis 二、神经网络建模 Neural Network 三、复习逻辑回归问题矩阵式 3.1 没有进行正则化 3.2 进行正则化 四、神经网络的代价函数 4.1 符号约定Notation 4.2 代价函数 五、反向传播算法 Backpropagation Alg 5.1 任务 5.2 一个…

python 打包

一、下载 pip install Pyinstaller 二、使用Pyinstaller 1、使用下载安装的方式安装的Pyinstaller打包方式 将需要打包的文件放在解压得到的Pyinstaller文件夹中&#xff0c;打开cmd窗口&#xff0c;把路径切换到当前路径打开命令提示行&#xff0c;输入以下内容&#xff08;最…

iOS架构篇-3 网络接口封装

iOS架构篇-3 网络接口封装 关键字:iOS,网络接口封装,Alamofire,swift 网络接口API通常都需要自己封装一套管理,这里以swift版的Alamofire为例. 实现功能: 1.暴露参数请求地址url、请求方法method、请求参数params、请求头header、请求响应response(响应数据、响应头resp…

coursera 《现代操作系统》 -- 第十一周 IO系统

本周要求 错题 下列I/O控制方式中&#xff0c;哪一个不需要硬件支持&#xff1f; 中断方式 轮询方式 DMA方式 I/O处理机方式 中断方式&#xff1a;中断控制器 轮询方式&#xff1a;CPU不断查询设备以了解其是否就绪 DMA:使用到了 DMA 控制器 4。 在设备管理中&#xff0c;缓冲…

matlab图形绘制基础(东北大学MOOC笔记)

%% 二维图形绘制 % 多纵轴曲线绘制 figure(1); t 0:0.01:2*pi; y1 sin(t); y2 10*cos(t); % plotyy(t, y1, t, y2); yyaxis left plot(t, y1); ylim([min(y1), max(y1)]); yyaxis right plot(t, y2); ylim([min(y2), max(y2)]);% 绘制极坐标图 figure(2); theta 0 : 0.01 :…

【转载】pycharm远程调试配置

pycharm远程调试配置https://www.cnblogs.com/liangjiongyao/p/8794324.html

Tornado 类与类组合降低耦合

转载于:https://www.cnblogs.com/shiluoliming/p/6760548.html

matlab生成多组多维高斯分布数据

matlab生成多组多维高斯分布数据 之所以写这么一个函数&#xff0c;是因为在练习用matlab实现聚类分析&#xff0c;用matlab生成的高斯分布数据可以作为很好的数据。当然&#xff0c;直接load进鸢尾花数据集也可以拿来练手&#xff0c;到后边再对鸢尾花数据集进行分析。 代码…

Android架构篇-5 CI/CD(持续集成、持续交付、持续部署)

Android架构篇-5 CI/CD(持续集成、持续交付、持续部署) CI CI是指持续集成,代码的更新会定期自动构建、测试并合并到公共仓库中,方便多分支时解决冲突问题 CD CD是指持续交付和/或持续部署,开发人员改动代码会自动测试提交到仓库,运维实施人员将其部署到生产环境中,方…

OpenCV中图像以Mat类型保存时各通道数据在内存中的组织形式及python代码访问各通道数据的简要方式...

OpenCV中图像以Mat类型保存时各通道数据在内存中的组织形式及python代码访问各通道数据的简要方式 以最简单的4 x 5三通道图像为例&#xff0c;其在内存中Mat类型的数据组织形式如下&#xff1a; 每一行的每一列像素的三个通道数据组成一个一维数组&#xff0c;一行像素组成一个…

CV01-语义分割笔记和两个模型VGG ResNet的笔记

目录 一、语义分割 二、VGG模型 2.1 VGG特征提取部分 2.2 VGG图像分类部分 三、ResNet模型 3.1 为什么是ResNet 3.2 11卷积调整channel维度大小 3.3 ResNet里的BottleNeck 3.4 Global Average Pooling 全局平均池化 3.5 Batch Normalization 学习语义分割理论&#x…

matlab编程实现k_means聚类(k均值聚类)

1. 聚类的定义 以下内容摘抄自周志华《机器学习》 根据训练数据是否拥有标记信息&#xff0c;机器学习任务可以大致分为两大类&#xff1a;“监督学习”&#xff08;supervised learning&#xff09;和“无监督学习”&#xff08;unsupervised learning&#xff09;。分类和回…