博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python核心编程:杂记4
阅读量:6854 次
发布时间:2019-06-26

本文共 5680 字,大约阅读时间需要 18 分钟。

  hot3.png

1. 类的一些基本概念

1. __init__

    可理解为构造函数。它在类实例化时候调用:

In [10]: class Book(object):   ....:     """Book information"""   ....:     def __init__(self, title):   ....:         self.title = title   ....:         print '__init__ called'   ....:         In [11]: book = Book('Python')__init__ called

2. 类的数据属性

    类的数据属性与实例无关,与类相关。

In [12]: class C(object):   ....:     foo = 100   ....:     In [13]: C.fooOut[13]: 100In [14]: C.foo += 1In [15]: C.fooOut[15]: 101In [16]: C.bar = 200In [17]: C.bar += 1In [18]: C.barOut[18]: 201
    但存在特殊的类属性:

C.__name__: 类C的名字

C.__doc__: 类C的文档字符串

C.__bases__: 类C的所有父类构成的元组

C.__dict__: 类C的属性

C.__module__: 类C定义所在的模块

C.__class__: 实例C对应的类

    实例如下:

In [31]: class C(object):   ....:     pass   ....: In [32]: class SubC(C):   ....:     """Sub class"""   ....:     pass   ....: In [33]: SubC.__name__Out[33]: 'SubC'In [34]: SubC.__doc__Out[34]: 'Sub class'In [35]: SubC.__bases__Out[35]: (__main__.C,)In [36]: SubC.__dict__Out[36]: 
In [37]: SubC.__module__Out[37]: '__main__'In [38]: SubC.__class__Out[38]: typeIn [39]: subc = SubC()In [40]: subc.__class__Out[40]: __main__.SubC

3. 实例属性

    通常是在__init__中定义实例属性。

    一般也可以在“运行时”创建实例属性,但是不推荐。而且在设计中,不推荐实例属性为列表或字典(可被修改的变量),因为这样很可能到最后你根本就不确定实例属性的值是多少。

    一般可以把字典/列表等设计成类属性,供所有的实例使用:

In [42]: class C(object):   ....:     arr = []   ....:     def __init__(self, num):   ....:         self.num = num   ....: In [44]: c1 = C(1)In [45]: c2 = C(2)In [46]: c1.numOut[46]: 1In [47]: c2.numOut[47]: 2In [48]: c1.arr.append(1)In [49]: c2.arr.append(2)In [50]: c1.arrOut[50]: [1, 2]In [51]: c2.arrOut[51]: [1, 2]
    而我们可以通过dir来查看所有实例属性:
In [52]: dir(c1)Out[52]: ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'arr', 'num']In [53]: c1.__dict__Out[53]: {'num': 1}

4. 静态方法和类方法

    可以使用装饰器来编写静态方法和类方法:

class TestStaticMethod(object):    @staticmethod    def foo():        print("calling static method foo()!")class TestClassMethod(object):    @classmethod    def foo(cls):        print("calling class method foo()")        print("foo() is part of class:%s" % cls.__name__)        		>>> tsm = TestStaticMethod()>>> tsm.foo()calling static method foo()>>> TestStaticMethod.foo()calling static method foo()>>> tcm = TestClassMethod()>>> tcm.foo()calling class method foo()foo() is part of class:TestClassMethod>>> TestClassMethod.foo()calling class method foo()foo() is part of class:TestClassMethod
    而静态方法和类方法的区别在stackoverflow上已说明:

2. 继承

1. __bases__类属性

    对任何子类,__bases__是一个包含其父类的集合的元组:

>>> class A(object): pass>>> class B(A): pass>>> class C(B): pass>>> A.__bases__(
,)>>> B.__bases__(
,)>>> C.__bases__(
,)

2. 通过继承覆盖方法

>>> class P(object):	def foo(self):		print("Hi, I am P-foo()")		>>> class C(P):	def foo(self):		print("Hi, I am C-foo()")		>>> c = C()>>> c.foo()Hi, I am C-foo()
      这时,如果我想调用父类的foo()方法,应该将实例c传入类P中:
>>> P.foo(c)Hi, I am P-foo()
     而更一般的情况是:我们通过调用super内建方法:
>>> class C(P):	def foo(self):		super(C, self).foo()		print("Hi, I am C-foo()")		>>> c = C()>>> c.foo()Hi, I am P-foo()Hi, I am C-foo()
核心笔记:重写__init__不会自动调用基类的__init__

    所以我们需要super:好处是我们不需要明确的给出任何基类名字

>>> class P(object):	def __init__(self):		print("calling P's constructor")		>>> class C(P):	def __init__(self):		super(C, self).__init__()		print("calling C's constructor")		>>> c = C()calling P's constructorcalling C's constructor

3. 多重继承

class P1(object):    def foo(self):        print("called P1-foo()")class P2(object):    def foo(self):        print("called P2-foo()")    def bar(self):        print("called P2-bar()")class C1(P1, P2):    passclass C2(P1, P2):    def bar(self):        print("called C2-bar()")class GC(C1, C2):    pass
     这里的多重继承,采取的查询方法为广度优先搜索:即对于GC来说,现搜索C1,C2.而旧类为深度搜索:现搜索C1,P1,然后搜索C2,P2:
>>> gc = GC()>>> gc.foo()called P1-foo()>>> gc.bar()called C2-bar()

3. 类,实例和其他对象的内建函数

issubclass():

    判断一个类是另一个类的子类或子孙类:

issubclass(sub, sup)
isinstance():

    判定一个对象是否是另一个给定类的实例:

isinstance(obj1, obj2)
obj1是类obj2的一个实例,或者是obj2的子类的一个实例时,返回True.

hasattr(),getattr(),setattr(),delattr():

    *attr()系列函数有两个参数,第一个参数是传递进来的方法,第二个参数为字符串属性名.

    hasattr()函数是布尔型,决定一个对象是否有一个特定的属性,一般用于访问某属性前先作一个检查.getattr()和setattr()函数相应的取得和赋值给对象的属性,getattr()读取不存在的属性时,引发AttributeError异常,除非给出那个可选的默认参数.setattr()将要么加入一个新的属性,要么取代一个已存在的属性.而delattr()函数会从一个对象中删除属性.

>>> class myClass(object):	def __init__(self):		self.foo = 100		>>> myInst = myClass()>>> hasattr(myInst, "foo")True>>> getattr(myInst, "foo")100>>> hasattr(myInst, "bar")False>>> getattr(myInst, "bar")Traceback (most recent call last):  File "
", line 1, in
getattr(myInst, "bar")AttributeError: 'myClass' object has no attribute 'bar'>>> setattr(myInst, "bar", "my attr")>>> dir(myInst)['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo']>>> getattr(myInst, "bar")'my attr'>>> delattr(myInst, "foo")>>> dir(myInst)['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar']
dir():

    显示模块的所有属性信息.

super():

    子类用于查找父类的属性.

vars():

    与dir()相似,只是给定的对象参数都必须有一个__dict__属性.

转载于:https://my.oschina.net/voler/blog/396125

你可能感兴趣的文章