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 函数
空,0和None都是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:
...

浙公网安备 33010602011771号