python基础0304

面向对象

面向对象其实是指把数据和功能结合起来,用称为对象的东西包裹起来组织程序的方法。类和对象是面向对象编程的两个主要方面。类创建一个新类型,而对象是这个类型的实例。

对象可以使用普通的属于对象的变量存储数据。属于一个对象或类的变量被称为域。对象也可以使用属于类的函数来具有功能。这样的函数被称为类的方法。域和方法可以合称为类的属性。

域有两种类型:属于每个实例/类的对象或属于类本身。它们分别被称为实例变量和类变量。

编程范式

编程范式指的是软件工程中的严谨方法学。编程语言的一种分类方式,它并不针对某种编程语言。就编程语言而言,一种语言可以适用多种编程范式。

常见的变成范式有 面向对象(oop)、函数式编程(fp)、面向过程等。通常每种语言都会提倡一些范式,也有的语言支持多种范式,python就是一种多范式语言,但是对OOP支持最好。

七周七语言

oop基本哲学

世界是由对象组成的;对象具有运动规律和内部状态;对象之间的相互作用和通讯构成世界。

对象的特性

唯一性:世界上没有两篇相同的树叶
分类性:分类是对显示世界的抽象

OOP的三大特征

  • 继承(共享的一种体现)
  • 多态(相同的操作,不同的对象,效果不同)
  • 封装

面向对象的本质

面向对象是对数据和行为的封装。但是有时候,数据仅仅是数据,方法仅仅是方法。

组织数据

面向过程中,数据和方法是分离的。门的例子:

door = [1,'close']

def open_door():
    door[1] = "open"

def close_door():
    door[1] = 'close'

class door:
    def __init__(self,number,status):
        self.number=number
        self.status=status
    
    def open(self):
        self.status = 'open'
    
    def close(self):
        self.status = 'close' 

其中单独类定义可以简写成

class ClassName:
        pass

等同于

class ClassName(object):
        pass

但是如果继承其他类的特性时父类不能省略,例如继承父类 door

class ClassName(door):
        pass

实例化过程

class A:

    def __new__(cls,*args,**kwargs):
        print("call__new__")
        print(cls)
        print(type(cls))
        return object.__new__(cls)

    def __init__(self,x):
        print("call__init__")
        print(self)
        print(type(self))
        s1 = set(dir(self))
        print(s1)
        self.x = x
        s2 = set(dir(self))
        print(s2)
        print(s2 - s1) 
	
a = A(5)
call__new__
<class '__main__.A'>                   这是一个类
<class 'type'>

call__init__
<__main__.A object at 0x7f9448384358>  这是一个实例
<class '__main__.A'>
{'__setattr__', '__class__', '__ne__', '__module__', '__reduce_ex__', '__repr__', '__subclasshook__', '__eq__', '__reduce__', '__init__', '__le__', '__str__', '__gt__', '__getattribute__', '__doc__', '__format__', '__new__', '__ge__', '__dir__', '__hash__', '__delattr__', '__sizeof__', '__weakref__', '__dict__', '__lt__'}
{'__setattr__', '__class__', '__ne__', '__module__', '__reduce_ex__', '__repr__', '__subclasshook__', '__eq__', '__reduce__', '__init__', '__le__', '__str__', '__gt__', '__getattribute__', '__doc__', '__format__', '__new__', '__ge__', '__dir__', 'x', '__hash__', '__delattr__', '__sizeof__', '__weakref__', '__dict__', '__lt__'}
{'x'}

class B:
    pass

print(type(B))
<class 'type'> #类的type 类型都是type

__new__方法在__init__方法之前调用,__new__方法创建类实例,__init__方法初始化类实例。__new__多用在元编程上,实现自定义的metaclass。

私有方法

class A:
    def __init__(self,x):
        self.__val = x
        
    def __add(self,y):
        self.__val += y
        
    def get_val(self):
        return self.__val
    
    def inc(self):
        self.__add(1)

a1 = A(5)
a1.get_val()
5
a1.inc()
a1.get_val()
6

双下划线开始,而不是双下划线结尾的方法,都属于私有变量或者私有方法,外部实例不能直接使用。

dir(a1)

['_A__add',
'_A__val',
'__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__',
'get_val',
'inc']

a1._A__val
6

私有变量或者私有方法并不是不可见的。这些方法和变量不能被实例直接调用,需要特殊转换才能使用,通常不建议使用私有变量或者私有变量。

类变量

class B:

   	val = [1,2,3]
   	
    def __init__(self,x):
   	    self.var = x

b1 = B(1)
b2 = B(2)

b1.val
[1, 2, 3]

b2.val
[1, 2, 3]

b1.val.append(4)

b2.val
[1, 2, 3, 4]

类变量最好用不可变对象,否则可能会污染到其他实例的值。

类方法

class A:
    __val = 3
    def __init__(self,x):
        print(type(self))
        self.x = x 
    
    def get_val_A(self):
        print(self)
        print(type(self))
        return self.__val
    
    @classmethod
    def get_val(cls):
        print(cls)
        print(type(cls))
        return cls.__val

a = A(1)
<class '__main__.A'>

a.get_val_A()
<__main__.A object at 0x7f23943eac88>
<class '__main__.A'>
3

a.get_val()
<class '__main__.A'>
<class 'type'>
3

A.get_val_A()
----------------------------------------------------------------
TypeError                      Traceback (most recent call last)
<ipython-input-31-f97b612ac9bb> in <module>()
----> 1 A.get_val_A()

TypeError: get_val_A() missing 1 required positional argument: 'self'

@classmethod 装饰器的作用就是把实例方法变成类方法。

静态方法

静态方法可以被类和实例使用,但是不能使用类变量。

类方法和静态方法的区别

class A:
    __val = 3 
    
    def __init__(self):
        self.x = 5
    @classmethod
    def print_val(cls):
        print(cls.x)
        
    @staticmethod
    def print_str():
        print()

a = A()

A.print_val()
----------------------------------------------------------------
AttributeError                 Traceback (most recent call last)
<ipython-input-60-cc5ba9d62a6f> in <module>()
----> 1 A.print_val()

<ipython-input-58-3c0aef6caa7d> in print_val(cls)
      6     @classmethod
      7     def print_val(cls):
----> 8         print(cls.x)
      9 
     10     @staticmethod

AttributeError: type object 'A' has no attribute 'x'

A.print_str()

----------------------------------------------------------------
NameError                      Traceback (most recent call last)
<ipython-input-61-05ca464a788a> in <module>()
----> 1 A.print_str()

<ipython-input-58-3c0aef6caa7d> in print_str()
     10     @staticmethod
     11     def print_str():
---> 12         print(__val)

NameError: name '_A__val' is not defined

静态方法:无法访问类属性和实例属性,相当于一个独立的方法,跟类没什么关系。

类方法:可以访问类属性,无法访问实例属性。

类属性小结

可见范围

  • 类级别

  • 类和实例都可以访问

  • 类变量 类定义的时候确定

  • 类方法

  • 实例级别

  • 只有实例可以访问

  • 实例变量 初始化的时候才确定(init)

  • 实例方法

私有和公有

  • 私有:只在内部可以访问
  • 公有:类外部也可以访问

魔术方法/特殊方法

对象的创建与销毁

  • _new_ 创建对象
  • _init_ 初始化对象
  • _del_ 销毁对象的时候使用
class A:
    def __new__(cls):
        print("call__new__")
        return object.__new__(cls)
    
    def __init__(self):
        print("call__init__")
        
    def method(self):
        print("call method")
        
    def __del__(self):
        print("call __del__")


a = A()
call__new__
call__init__
a.method()
call method
del a 
call __del__

可视化对象

class A:
    pass

a = A()
print(a)
<__main__.A object at 0x7f1a474c5a58>

class A:
    def __init__(self,name):
        self.name = name
    
    def __repr__(self):
        return self.name
    
    def __str__(self):
        return "call__str__name is {0}".format(self.name)
    
    def __bytes__(self):
        return "call __str__name is {0}".format(self.name).encode("utf-8")

a = A("sunchao")
print(repr(a))
sunchao

str(a)
'call__str__name is sunchao'

bytes(a)
b'call __str__name is sunchao'

repr(a)
'sunchao'
  • Python对bytes类型的数据用带b前缀的单引号或双引号表示
  • ASCLL --> Unicode(内存) --> UTF-8(存储)
  • bytes 的每个字符都只占用一个字节
  • Unicode表示的str通过encode()方法可以编码为指定的bytes
  • 从网络或磁盘上读取了字节流数据是bytes,要把bytes变为str,要用decode()

比较运算符重载

class Person():
    def __init__(self,age):
        self.age = age
        
    def __lt__(self,other):
        print("lt")
        return self.age < other.age
    
    def __le__(self,other):
        print("le")
        return self.age <= other.age
    
    def __eq__(self,other):
        print("eq")
        return self.age == other.age
    
    def __ne__(self,other):
        print("ne")
        return self.age != other.age
    
    def __gt__(self,other):
        print("gt")
        return self.age > other.age
    
    def __ge__(self,other):
        print("ge")
        return self.age >= other.age

p1 = Person(20)
p2 = Person(30)
p1 > p2
False

bool 函数

0None都是False。

class Grok:
    def __init__(self,val):
        self.val = val
    
    def __bool__(self):
        return not self.val

grok = Grok(True)
bool(grok)
False

伪造空列表,实际上空默认是False。

class List():
    def __init__(self,*args):
        self.val = args
        
    def __bool__(self):
        return True
    
    def __len__(self):
        return  len(self.val)

b = List()
bool(b)
True

len(b)
0

hash() 与可 hash 对象

class Grok():
    def __init__(self,val):
        self.val = val
        
    def __hash__(self):
        pass

a = Grok("google")
hash(a)

import sys
sys.hash_info.width
64

help(sys.hash_info.width)
Help on int object:
...

Python3 官方文档

posted @ 2016-03-04 17:02  蓝色骨头  阅读(168)  评论(0)    收藏  举报