3 When Objects are Alike

1、class variables && instance variables

class Contact:
    all_contacts = []
    str = ""
    def __init__(self,name,email):
        self.name = name
        self.email = email
        #self.all_contacts.append(self)
        Contact.all_contacts.append(self)

class variables,即类变量,它是类定义的一部分,all_contacts即是,如同C++里的static,是属于类的,所有实例共享这个类变量;instance variables,实例变量,它是属于某个实例的,类中用self.引用的即是。需要注意的时,类变量在引用时一定是用class.classVariable这种方式,而不能用self.classVariable或instance.classVariable,有时这两种方式虽然也是可以的,但更多时间会出错,这涉及到Python变量可变与不可变:

python中,一切都是对象,故不存在传值还是传址,因为全都是传址。而这些变量中,又分为:

  • 可变对象:可变是指它的内容是可变的,有列表、字典等
  • 不可变对象:元组、字符串、数值型等
a = 1 #申请一段内存,值为1,把a指向这段内存
b = a #把b指向a的内存
b = 2 #因为数值型不可变,所以又申请一段内存,值为2,把b指向这段内存
print a is b #False,地址不相同
a = [1,2]
b = a #b指向a指向的内存
b[0] = 3
print a is b #True,因为list的内容是可变的,故还是指向同一段内存
b = [] #类型不可变,故申请一段内存,把b指向这段新的内存,而a不变
print a is b #False


2、继承

class Supplier(Contact):
    def test(self):
        print "YES"

在类后面的括号里写明父类即表示继承,如果没有写父类,python默认会继承object这个类。同样,如果没有重载__init__这个函数,则默认调用父类的__init__。

3、继承内置对象

现在我们有一个需求:需要在all_contents里找到所有name==v的数据:

class Contact:
    all_contacts = []
    str = ""
    
    def __init__(self,name,email):
        self.name = name
        self.email = email
        self.str = name
        Contact.str = email
        Contact.all_contacts.append(self)
        
    def search(self,name):
        match_contacts = []
        for contact in Contact.all_contacts:
            if contact.name == name:
                match_contacts.append(contact)
        return match_contacts
        
        
c = Contact("moment","moment@gmail.com")
b = Contact("mmm","F")
可以在Contact里加一个search函数,然后通过instance.func的方式调用(不能用class.func调用,会报错,不知道为什么,能用这种方式访问变量,却不能访问函数)。但这个方法属于all_contacts更好,因为它是个list,且不属于任何实例。我们可以这样:

class ContactList(list):
    
    def search(self,name):
        m = []
        for contact in self:
            if name is contact.name:
                m.append(contact)
        return m
    
    
class Contact:
    all_contacts = ContactList()
    
    def __init__(self,name,email):
        self.name = name
        self.email = email
        self.str = name
        Contact.str = email
        Contact.all_contacts.append(self)

我们先构造了一个继承list的类,然后定义了search方法,并将all_contacts变为这个类的实例。

当然,如果有需要,object,list,set,dict,file,str等都可以被继承。

4、override

class Supplier(Contact):
    
    def __init__(self,name,email,phone):
        super(Supplier, self).__init__(name,email)
        self.phone = phone
在重载时,我们可以用super(子类,self)来引用父类的函数。

注意:super函数只能应用于新类,新类是指那些什么都不用继承,那就继承object的类。在上面的例子中,Contact什么都没继承,而其子类Supplier中引用了super,所以会报错:TypeError: must be type, not classobj。只要将Contact继承object即可。
5、多继承

假设Supplier有地址需要存储,我们建立AdderssHolder类:

class AddressHolder:
    def __init__(self, city, street):
        self.city = city
        self.street = street
而Supplier可以这样继承:

class Supplier(Contact, AddressHolder):
    
    def __init__(self,name,email,phone, city, street):
        Contact.__init__(self, name, email)
        AddressHolder.__init__(self, city, street)
        self.phone = phone

在初始化时,我们指定了父类,这种方法有潜在的危险:假如Contact和AddressHolder有同一个父类A,那么父类A的__init__可能会被多次调用,如


因为图形如钻石,故称作diamond inheritance。当然,我们会想到super这个函数,如在__init__里直接super().__init__(),但实验发现,用super会导致调用顺序出问题:

class BaseClass(object):
    num_base_calls = 0
    def call_me(self):
        print("Calling method on Base Class")
        self.num_base_calls += 1
        
class LeftSubclass(BaseClass):
    num_left_calls = 0
    def call_me(self):
        print "left: before super"
        super(LeftSubclass,self).call_me()
        print("Calling method on Left Subclass")
        self.num_left_calls += 1
        
class RightSubclass(BaseClass):
    num_right_calls = 0
    def call_me(self):
        print "right: before super"
        super(RightSubclass,self).call_me()
        print("Calling method on Right Subclass")
        self.num_right_calls += 1
        
class Subclass(LeftSubclass, RightSubclass):
    num_sub_calls = 0
    def call_me(self):
        super(Subclass,self).call_me()
        print("Calling method on Subclass")
        self.num_sub_calls += 1


s = Subclass()
s.call_me()
print(s.num_sub_calls, s.num_left_calls, s.num_right_calls,s.num_base_calls)

这里答案会输出:

left: before super
right: before super
Calling method on Base Class
Calling method on Right Subclass
Calling method on Left Subclass
Calling method on Subclass
(1, 1, 1, 1)

很明显,Base是只被执行了一次。但我们看调用顺序,它是先调用了LeftSubclass的call_me,然后它里面的super却指向了RightSubclass。其实,新式类里的调用顺序可以用__mro__来查看:

print Subclass.__mro__

(<class '__main__.Subclass'>, <class '__main__.LeftSubclass'>, <class '__main__.RightSubclass'>, <class '__main__.BaseClass'>, <type 'object'>)

可以看到,类的调用顺序是Subclass -> Left -> Right -> Base,类似“广搜”,一旦找到后就马上返回。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数字乡村和智慧农业的数字化转型是当前农业发展的新趋势,旨在通过应用数字技术,实现农业全流程的再造和全生命周期的管理服务。中国政府高度重视这一领域的发展,提出“数字中国”和“乡村振兴”战略,以提升国家治理能力,推动城乡融合发展。 数字乡村的建设面临乡村治理、基础设施、产业链条和公共服务等方面的问题,需要分阶段实施《数字乡村发展战略纲要》来解决。农业数字化转型的需求包括满足市民对优质农产品的需求、解决产销对接问题、形成优质优价机制、提高农业劳动力素质、打破信息孤岛、提高农业政策服务的精准度和有效性,以及解决农业融资难的问题。 数字乡村建设的关键在于构建“1+3+4+1”工程,即以新技术、新要素、新商业、新农民、新文化、新农村为核心,推进数据融合,强化农业大数据的汇集功能。数字农业大数据解决方案以农业数字底图和数据资源为基础,通过可视化监管,实现区域农业的全面数字化管理。 数字农业大数据架构基于大数据、区块链、GIS和物联网技术,构建农业大数据中心、农业物联网平台和农村综合服务指挥决策平台三大基础平台。农业大数据中心汇聚各类涉农信息资源和业务数据,支持大数据应用。信息采集系统覆盖市、县、乡、村多级,形成高效的农业大数据信息采集体系。 农业物联网平台包括环境监测系统、视频监控系统、预警预报系统和智能控制系统,通过收集和监测数据,实现对农业环境和生产过程的智能化管理。综合服务指挥决策平台利用数据分析和GIS技术,为农业决策提供支持。 数字乡村建设包括三大服务平台:治理服务平台、民生服务平台和产业服务平台。治理服务平台通过大数据和AI技术,实现乡村治理的数字化;民生服务平台利用互联网技术,提供各类民生服务;产业服务平台融合政企关系,支持农业产业发展。 数字乡村的应用场景广泛,包括农业生产过程、农产品流通、农业管理和农村社会服务。农业生产管理系统利用AIoT技术,实现农业生产的标准化和智能化。农产品智慧流通管理系统和溯源管理系统提高流通效率和产品追溯能力。智慧农业管理通过互联网+农业,提升农业管理的科学性和效率。农村社会服务则通过数字化手段,提高农村地区的公共服务水平。 总体而言,数字乡村和智慧农业的建设,不仅能够提升农业生产效率和管理水平,还能够促进农村地区的社会经济发展,实现城乡融合发展,是推动中国农业现代化的重要途径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值