精华内容
下载资源
问答
  • __init__方法 如果一个Python方法以双下划线作为开始和结束标志,这表明这是一个特殊的方法,你可以把它...这里Python和它们有一点点不同,Python有一个构造函数和一个初始化函数。在大部分情况下,构造函数很少能...

    __init__方法

    如果一个Python方法以双下划线作为开始和结束标志,这表明这是一个特殊的方法,你可以把它理解成Python内置方法,所以自己在自定义方法的时候避免这样定义方法。

    对象初始化
    大部分面向对象语言都有一个叫做构造函数的特殊方法,当它被创建的时候就会创建和初始化对象。这里Python和它们有一点点不同,Python有一个构造函数和一个初始化函数。在大部分情况下,构造函数很少能用得到,这里我们着重来看下类的初始化函数。
    类的初始化函数除了一个特殊的名字外,和其他方法没有什么不同。

    一、创建一个类(class)

    在Python中,可以通过class关键字定义自己的类(class),然后通过自定义的类创建实例对象。

    最简单的类如下:(不包含任何属性和方法)

    class FirstClass:
        pass
    

    利用这个类创建两个对象a和b,并打印:

    a = FirstClass()
    b = FirstClass()
    print(a)
    print(b)
    

    结果为

    <__main__.FirstClass object at 0x00000183514FCB00>
    <__main__.FirstClass object at 0x00000183514FC080>
    

    这说明a和b位于不同的内存区域,因此是两个对象

    二、查看类的继承

    可以调用__bases__方法查看一个类的父类,

    FirstClass.__bases__
    

    得到

    (object,)
    

    说明FirstClass继承了object类

    • 在Python3中,所有类都默认继承object,因此object是所有类的父类。这一点与Java是相同的。
    • 但是Python中允许一个子类继承多个父类,而Java要求一个子类只能继承一个父类。
    • Python和Java都允许一个父类可以被多个子类继承。

    想要更具体地了解Python类的继承,请查阅引用[2]PYTHON3中 类的继承

    注意:
    (1) 在这里,__bases__和__init__都是Python内置方法,标志是以__为起止符号。__name__也一样。
    (2) __bases__只能被class调用,不能被对象调用,如下所示。

    在这里插入图片描述

    三、利用点记法给类添加属性

    上述FirstClass类不包含任何属性和方法,我们可以通过点记法对**类的实例化对象(instance)**进行属性添加:

    <object>.<attribute>=<value>
    

    其中 value 可以是 Python 的内置数据类型、其他的对象,也可以是一个函数或者另一个类。

    c = FirstClass()
    d = FirstClass()
    c.atr = 1
    d.atr = 2
    d.btr = 3
    print(c.atr)
    print(d.atr)
    print(d.btr)
    

    输出

    
    
    1
    2
    3
    
    • 可以给一个对象添加一个或多个属性,例如上面的atr和btr。
    • 属性能够重新赋值。
    d.btr = 4
    print(d.btr)
    
    4
    

    四、添加方法

    现在为上面的FirstClass类添加属性和方法,属性包括x和y坐标,方法包括2个:reset 重置坐标到原点(0,0)和 rightmove2右移2个单位。**

    用def定义了一个类方法,它和普通函数有一点不同,就是它有一个self参数。
    方法中的这个self参数,就是对调用该方法(method)的实例对象(instance)的一个引用(reference)

    class FirstClass:
        def reset(self):
            self.x = 0
            self.y = 0
        
        def rightmove2(self):
            self.x = 2
            self.y = 0
                  
    

    创建FirstClass的实例对象p,给属性赋值并调用方法:

    p = FirstClass()
    p.x = 1
    p.y = 2
    print(p)
    print(p.x)
    print(p.y)
    

    输出为

    <__main__.FirstClass object at 0x00000183515F2B38>
    1
    2
    

    调用reset方法:

    p.reset()
    print(p)
    print(p.x)
    print(p.y)
    

    输出为

    <__main__.FirstClass object at 0x00000183515F2B38>
    0
    0
    

    调用rightmove2方法:

    p.rightmove2()
    print(p)
    print(p.x)
    print(p.y)
    

    输出为

    <__main__.FirstClass object at 0x00000183515F2B38>
    2
    0
    

    可见,p所在的内存位置保持不变,因此都是同一个对象。

    用def定义了一个类方法,它和普通函数有一点不同,就是它有一个self参数。
    方法中的这个self参数,就是对调用该方法(method)的实例对象(instance)的一个引用(reference)

    在这里,self 指对调用 reset 和 rightmove2 方法实例对象 p 的一个引用

    你注意到我们调用p.reset()方法时候,并没有给它传入self参数。这里是Python帮我们自动传入:它知道我们正在调用p对象的一个方法,所以会自动把这个对象 p 传入这个方法 reset。也就是说:p.reset() 等价于 Point.reset(p)
    因此,Python 会自动把调用某个类的方法的对象作为 self 参数传入该方法

    下面实现一个简单的计算两点间距离的类:

    import math
    
    class Point:
        def move(self, x, y):
            self.x = x
            self.y = y
        def reset(self):
            self.move(0, 0)
            
        def distance(self, other):
            return math.sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2)
        
    

    创建对象并调用方法。传参只需要考虑一般参数,无须显示地传入self参数,Python会自动将调用方法的对象传入self参数。

    p1 = Point()
    p2 = Point()
    p1.move(3, 4)
    p2.move(5, 12)
    
    print(p1.distance(p2))
    
    print(p2.distance(p2))
    

    结果为

    8.246211251235321 # p1与p2之间的距离
    0.0  # p2与自身的距离当然为0
    

    将p1重置,再计算p1到p2的距离。

    p1.reset()
    print(p1.distance(p2))
    
    13.0  # 距离变为13
    

    [参考教程]

    [1] Python类中__init__函数和self参数的关系
    [2] PYTHON3中 类的继承

    展开全文
  • Python类初始化方法

    千次阅读 2018-03-13 11:10:53
    摘自Mastering Object-oriented Python隐式的基类——objectPython是面向对象程序设计语言,有一个类似root的基础object。任何自定义的,都会隐式继承object。class X: pass print(X.__class__) # &lt;...

    摘自Mastering Object-oriented Python

    隐式的基类——object

    Python是面向对象程序设计语言,有一个类似root的基础类object类。任何自定义的类,都会隐式继承object。

    class X:
        pass
    
    print(X.__class__)
    # <class 'type'>
    print(X.__class__.__base__)
    # <class 'object'>
    

    基类中的初始化方法

    • 延迟赋值

    这是指先创建类模板,然后在实例中定义属性并赋值。在Python中,延迟赋值的合法的,但是会存在潜在问题,因此要尽量避免这样的用法。

    在基类中实现__init__()方法

    每当创建一个对象,Python会先创建一个空对象,然后调用该对象的__init__()函数。

    一个常见的多态设计

    class Card:
        def __init__(self,rank,suit):
            self.suit = suit
            self.rank = rank
            self.hard, self.soft = self._points()
    
    class NumberCard(Card):
        def _points(self):
            return int(self.rank), int(self.rank)
    
    class AceCard(Card):
        def _points(self):
            return 1, 11
    
    class FaceCard(Card):
        def _points(self):
            return 10, 10
    

    使用__init__()方法创建常量清单

    可以把创建好的花色对象做缓存,构建一个常量池,使得在调用时对象可被重用,那么性能将得到显著的提升。

    class Suit:
        def __init__(self, name, symbol):
            self.name = name
            self.symbol = symbol
    
    Club, Diamond, Heart, Spade = Suit('Club','♠'), Suit('Diamond','♦'), Suit('Heart','♥'), Suit('Spade','♣')
    
    Cards = [AceCard('A', Spade), NumberCard('2',Spade), NumberCard('3',Spade)]
    

    使用工厂函数调用__init__()

    可以使用工厂函数来完成所有的Card对象的创建。在Python中实现工厂有两种途径

    • 定义一个函数,返回不同类的对象
    • 定义一个类,包括了创建对象的方法

    一个用来生成Card子类对象的工厂函数例子

    def card(rank, suit):
        if rank == 1: return AceCard('A',suit)
        elif 2 <= rank < 11: return NumberCard(str(rank),suit)
        elif 11 <= rank < 14:
            name = {11: 'J', 12: 'Q', 13: 'K'}[rank]
            return FaceCard(name, suit)
        else:
            raise Exception('Rank out of range.')
    
    deck = [card(rank,suit) for rank in range(1,14)
            for suit in (Club, Diamond, Heart, Spade)]
    

    这里需要注意的是if语句的结构,else语句没有做一些其他步骤,而只是单纯地抛出了一个异常。像这样的catch-all else语句的使用方式是有争议的。

    使用elif简化设计来获得一致性

    工厂方法card()中包括了两个很常见的结构

    • if-elif序列
    • 映射

    这是一个没有使用映射Card工厂类的例子

    def card3(rank, suit):
        if rank == 1: return AceCard('A',suit)
        elif 2 <= rank < 11: return NumberCard(str(rank),suit)
        elif rank == 11: return FaceCard('J', suit)
        elif rank == 12: return FaceCard('Q', suit)
        elif rank == 13: return FaceCard('K', suit)
        else:
            raise Exception('Rank out of range.')
    

    相比上一个版本,这个函数在实现上获得了更好的一致性。

    使用映射和类来简化设计

    下面这个例子用映射来实现,把rank映射为对象,然后又把rank值和suit值作为参数传入Card构造函数来创建Card实例。

    def card4(rank, suit):
        class_ = {1: AceCard, 11: FaceCard, 12: FaceCard, 13: FaceCard}.get(rank, NumberCard)
        return class_(rank, suit)
    

    实现两部分映射

    • 并行映射
      不推荐使用

    • 映射到一个牌面值的元组

    def card5(rank, suit):
        class_, rank_str = {1: (AceCard,'A'),
                            11: (FaceCard,'J'),
                            12: (FaceCard,'Q'),
                            13: (FaceCard,'K')}.get(rank,(NumberCard,str(rank)))
        return class_(rank_str, suit)
    
    • partial函数设计

    partial()函数在面向对象编程中不是很常用。

    • 工厂模式的流畅API设计
    class CardFactory:
        def rank(self, rank):
            self.class_, self.rank_str = {1: (AceCard,'A'),
                                          11: (FaceCard,'J'),
                                          12: (FaceCard,'Q'),
                                          13: (FaceCard,'K')}.get(rank,(NumberCard,str(rank)))
            return self
    
        def suit(self, suit):
            return self.class_(self.rank_str, suit)
    
    card8 = CardFactory()
    deck8 = [card8.rank(r+1).suit(s) for r in range(13)
             for s in (Club, Diamond, Heart, Spade)]
    

    这种方法并没有利用__init__()在Card类层次结构中的作用,改变的是调用者创建对象的方式。

    在每个子类中实现__init__()方法

    class Card:
        def __init__(self, rank, suit, hard, soft):
            self.suit = suit
            self.rank = rank
            self.hard = hard
            self.soft = soft
    
    class NumberCard(Card):
        def __init__(self, rank, suit):
            super().__init__(str(rank), suit, rank, rank)
    
    class AceCard(Card):
        def __init__(self, rank, suit):
            super().__init__('A', suit, 1, 11)
    
    class FaceCard(Card):
        def __init__(self, rank, suit):
            super().__init__({11: 'J', 12: 'Q', 13: 'K'}[rank], suit, 10, 10)
    

    使用__init__()方法和工厂函数之间存在一些权衡。通常直接调用比“程序员友好”的__init__()函数并把复杂性分发给工厂函数更好。

    简单的组合对象

    一个组合对象也可以称作容器

    设计集合类,通常有如下3种策略:

    • 封装
    • 扩展
    • 创建

    封装集合类

    定义Deck类,内部实际调用的是list对象。Deck类的pop()方法只是对list对象响应函数的调用。

    class Deck:
        def __init__(self):
            self._cards = [card8.rank(r+1).suit(s) for r in range(13)
                           for s in (Club, Diamond, Heart, Spade)]
            random.shuffle(self._cards)
    
        def pop(self):
            return self._cards.pop()
    

    扩展集合类

    pop()函数只需继承自list集合就可以很好地工作,其他函数也一样。

    class Deck2(list):
        def __init__(self):
            super().__init__(card8.rank(r+1).suit(s) for r in range(13) for s in (Club, Diamond, Heart, Spade))
            random.shuffle(self)
    

    完成组合对象的初始化

    __init__()初始化方法应当返回一个完整的对象,这是理想的情况。

    不带__init__()方法的无状态对象

    对于策略模式的对象来说这是常见的设计。一个策略对象以插件的形式符合在主对象上来完成一种算法或逻辑,例如GameStrategy类。



    作者:plutoese
    链接:https://www.jianshu.com/p/a5cb4070e733
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    展开全文
  • 本文给大家介绍一下Python初始化时候的特殊方法,通过实例给大家做了分析,一起来学习下。
  • Python初始化方法__init__()修改变量

    千次阅读 2020-11-09 15:42:00
    文章目录 问题描述 解决方案 参考文献 问题描述 【需求】 默认情况下,不初始化,可以直接调用类方法。 若初始化,修改变量,对应类方法也发生改变。 解决方案 修改变量:类名.属性名 = xxx class A(object): ...

    问题描述

    【需求】

    1. 默认情况下,不初始化,可以直接调用类方法。
    2. 若初始化,修改类变量,对应类方法也发生改变。




    解决方案

    在这里插入图片描述
    修改类变量:类名.属性名 = xxx

    class A(object):
        data = 1
    
        def __init__(self, data=2):
            A.data = data
    
        @classmethod
        def get_data(cls):
            return cls.data
    
    
    if __name__ == '__main__':
        print(A.get_data())  # 1
        print(A().get_data())  # 2
    

    关键点在于A.data = data




    参考文献

    1. Python基础-类变量和实例变量
    展开全文
  • python:初始化方法( __init__)

    千次阅读 2019-02-06 22:28:20
    使用类名()创建对象时,Python解释器会首先在内存中开辟一个足够的空间可以存下创建的对象,然后调用初始化方法,在初始化方法中给对象的所有属性设置初始值(为属性设置初始值的方法叫做初始化方法),对象的初始...

    初始化方法就是 __init__方法,__init__是对象的内置方法。
    使用类名()创建对象时,Python解释器会首先在内存中开辟一个足够的空间可以存下创建的对象,然后调用初始化方法,在初始化方法中给对象的所有属性设置初始值(为属性设置初始值的方法叫做初始化方法),对象的初始化方法为__init__方法。

    方法是专门用来定义类所包含属性的方法。

    class Cat():
        def __init__(self, name):
            print('这是一个初始化方法')
            self.name = name
    
        def eat(self):
            print('%s爱吃鱼' % self.name)
    
    
    cat = Cat('tom')
    print(cat.name)
    
    hello_kitty = Cat('HK')
    print(hello_kitty.name)
    hello_kitty.eat()
    运行结果:
    	这是一个初始化方法
    	tom
    	这是一个初始化方法
    	HK
    	HK爱吃鱼
    
    展开全文
  • python类初始化属性在def init()中定义,实例化对象后可直接调用 python类初始化属性在def func()中定义,实例化对象后,先调用调用函数,再调用属性 class Mdata(object): def __init__(self): self.mydata1 = ...
  • Python类初始化 (Python class init) Whenever a beginner starts learning the Python programming language, they come across something like __init__ which usually they don’t fully understand. In this ...
  • python中子继承初始化方法

    千次阅读 2019-05-18 17:08:20
    python3.x版本:  def __init__(self,新定义子类属性)  super().__init__(父类属性) python2.7版本:  def __init__(self,新定义子类属性)  super(子类名, self).__init__(父类属性) 子类...
  • 1.面向对象 概述:  面向过程的程序设计把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来...在Python中,所有数...
  • 的成员主要由实例方法和数据成员组成。在中创建了的成员后,可以通过的实例进行访问 实例方法 是指在中定义的函数。该函数是一种在的实例上操作的函数。 ‘’‘ 语法: class 类名(): 的说明信息 def ...
  • python 的继承及初始化

    千次阅读 2019-05-17 09:38:39
    #初始化基类函数方法2:使用super函数,每个都被初始化一次,建议方式 super(C3, self).__init__(**kwargs) #按照继承关系逐步初始化基类 def myprint(self): #函数重写 print 'cbase3' if __name__=='__...
  • 的创建语法: ... 内的变量和方法能被此类所创建的所有实例所共同拥有  说明:  类名必须是标识符(与变量名命名规则相同,建议首字母大写)  类名实质上就是变量,它绑定一个实例 ...
  • 1.初始化实例化属性。可接受任意关键字参数,并把他们都作为属性赋值给实例。使用**kw,除了可以直接使用self.name = ‘xxx’设置一个属性外,还可以通过setattr(self, ‘name’, ‘xxx’)设置属性。class Pers
  • 我也可以同样创建属于自己的,然后可以直接初始化性,调用里面的方法,及属性。 1、的创建,我们来创建一个动物的,可以直接用class来创建一个。我们来看一下他的基本结构。 class加上类名然后加:号,里面...
  • PYTHON 定义,属性,初始化

    千次阅读 2020-05-01 17:12:02
    文章目录PYTHON 类定义,属性,初始化类定义类的私有属性类方法类初始化和析构初始化析构 PYTHON 类定义,属性,初始化 为了代码的编写方便简洁,引入了类的定义; 一般,使用 class 语句来创建一个新类,class...
  • python 字典初始化方法 全!!!

    万次阅读 2019-09-02 18:32:21
    python 中字典还是比较常用的,可惜自己一直记不住,好记性不如烂笔头这话说的一点没错 方法一: (这个是比较常见的) d1 = {'x': 1, 'y': 2} print(d1['x']) >>> 1 当然也有这种特别好理解,但是...
  • 这是因为两个都没names这个变量,但子类的构造函数,即初始化函数,即实例化函数__init__中有新建一个成员变量name,所以使用name没问题而names有问题。 如果Father的getName函数中反回的是self.name而不是...
  • 深入理解python类的创建和初始化

    千次阅读 2019-01-10 09:10:13
    在理解元之前,你需要先掌握Python中的Python的概念借鉴于Smalltalk,这显得有些奇特。在大多数编程语言中,就是一组用来描述如何生成一个对象的代码段。在Python中这一点仍然成立: class ...
  • 初始化方法 当使用 类名() 创建对象的时,会自动执行以下操作: 1.为对象在内存中分配空间---------创建对象 2.为这个对象的属性设置初始值----初始化方法(init) 这个初始化方法就是__init__方法,__init__是对象的...
  • python类初始化属性在def __init__()中定义,实例化对象后可直接调用 python类初始化属性在def func()中定义,实例化对象后,先调用调用函数,再调用属性 代码 class Mdata(object): def __init__(self): ...
  • 类的初始化过程和类的三种方法类初始化过程类内的三种方法 类的初始化过程 在执行类的初始化的时候,比如a = A(),先是执行了__new__(cls) 方法,根据传入的cls来分配空间,然后再执行对象的__init__(self) 方法。...
  • python 自定义初始化对象

    万次阅读 2020-06-29 18:13:41
    python自定义,需用到class关键字 ...初始化对象直接在后面添加括号即可 # 初始化对象 p = Person('汉城节度使', '50') 获取对象信息,直接对象.属性即可 # 打印对象信息 print("name:" + p.nam.
  • Python初始化列表

    万次阅读 多人点赞 2019-04-29 18:17:49
    Python初始化列表 下面我们就来介绍在Python中初始化列表(我们创建大小为1000并使用零初始化的列表)的一些方法。 1)方法一:使用for循环和append()函数 arr = [] for i in range(1000): arr.append(0) 2)方法...
  • Python3中子调用父类的初始化方法

    千次阅读 2019-09-07 11:16:29
    Python3中子如何调用父类的初始化方法python3中,子类可以重写父类的方法(及重载)。因为初始化方法是在创建对象时自动调用的,很容易在这方面出错。本文以子类调用父类初始化方法为切入点,解决此问题。 ...
  • python 结构体数组的正确初始化方法

    千次阅读 2020-09-22 20:28:09
    特别注意 列表=[对象]*N 这种写法是错误的,因为初始化得到的N个对象指向相同的地址,实验如下: class Phase_struct: pass #方法1 phases1 = [Phase_struct(),Phase_struct(),Phase_struct()] print(id(phases1[0]...
  • Python中子调用父类的初始化方法

    万次阅读 2018-03-17 22:07:17
    Python中子调用父类的初始化方法 前言 python中进行面向对象编程,当在子类的实例中调用父类的属性时,由于子类的__init__方法重写了父类的__init__方法,如果在子类中这些属性未经过初始化,使用时就会出错。...
  • 通过之前四篇的介绍: ...【python】详解class的方法:实例方法类方法、静态方法(三)详见链接 【python】详解class的访问控制:单下划线与双下划线_(四)详见链接 Python相关的一些基本
  • 1.中的初始化方法:语法:def _init_(self):在java中构造和初始化是一个方法,但是在pthon3中构造方法和初始化方法是分开的 2.构造方法:语法:def _new_(cls,*args,**kwargs):注意构造方法必须有返回值,并且...
  • 更好一点的方法可以使用python的深拷贝。 import copy class Node (object) : def __init__ (self ,childrenList=[], name = '.' ) : self.name = name self.childrenList = copy.deepcopy...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 418,993
精华内容 167,597
关键字:

python类的初始化方法

python 订阅