python 人生苦短,我学Python
Posted IT_Holmes
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 人生苦短,我学Python相关的知识,希望对你有一定的参考价值。
文章目录
1. 对象(Object)
理解好对象和实例关系。
2. 类(class)
定义类:
class MyClass():
pass
# print(MyClass);
mc = MyClass(); # mc就是通过MyClass创建的对象,mc是MyClass的实例。
print(mc); # <__main__.MyClass object at 0x0000014E41FD4B20>
isinstance()用来检查一个对象是否是一个类的实例。
class MyClass():
pass
# print(MyClass);
mc = MyClass(); # mc就是通过MyClass创建的对象,mc是MyClass的实例。
result = isinstance(mc,MyClass); # 检查mc是否时MyClass的实例
print(result); # True
3. 对象的创建流程
添加属性:
语法:对象.属性名 = 属性值;
class MyClass():
pass
# print(MyClass);
mc = MyClass();
mc.name = '张三'; # 创建一个name属性。
print(mc.name);
方法调用:
在类中定义函数,类中的定义的函数,我们称为方法。调用方法也就是上面的方法调用。
方法调用语法:对象.方法名()
class Person():
a = 10;
b = 20;
# 每一个方法必须定义一个形参,因为方法调用是,默认传递一个参数。
def say_hello(a):
print(a);
print('你好,张三');
p1 = Person();
p2 = Person();
print(p1.a,p1.b);
print(p2.a,p2.b);
p1.say_hello();
p2.say_hello();
方法调用和函数调用的区别:
如果是函数调用,则调用时传入几个参数,就会有几个实参。
但是如果时方法调用,默认传递一个参数,所以方法中至少要定义一个形参。
4. 属性和方法查找的流程
1.当我们调用一个对象的属性时,解析器会先在当前对象中寻找是否函数该属性。
2.如果有,则直接返回当前对象的属性值。
3.如果没有,则去当前对象的类对象中去寻找,如果有则返回类对象的属性值,如果没有则报错。
总结:
类方法传递的第一个参数self:
其实,self就是实例对象
class Person():
name = '默认名字';
def say_hello(self):
# 方法每次调用时,解析器都会自动传递第一个实参。
# 通过打印知道,这里的self就是实例对象p1或p2,看谁调用。
# 一般我们都将这个参数命名为self。
print(self);
print('你好,%s'%self.name);
p1 = Person();
p2 = Person();
p1.name = '张三';
p2.name = '李四';
print(p1);
p1.say_hello();
print(p2);
p2.say_hello();
# 通过打印知道,这里的p1或p2和上面的self是一样的实例对象,看谁调用。
# <__main__.Person object at 0x0000029CFDD84B20>
# <__main__.Person object at 0x0000029CFDD84B20>
# 你好,张三
# <__main__.Person object at 0x0000029CFDDB7FD0>
# <__main__.Person object at 0x0000029CFDDB7FD0>
# 你好,李四
5. 类的特殊方法 init
- 在类中,可以定义写特殊方法(也叫魔术方法)。
- 特殊方法都是以__(双下划线)开头,__(双下划线)结尾的。 例如:__init__ 。
- 特殊方法不需要我们来调用,像__init__不要去调用!!。
- 特殊方法将会在特殊时刻自动调用。
创建对象的流程
1.创建一个变量。
2.在内存中创建一个新对象。
3.执行类的代码块中中的代码(只在类定义的时候执行一次)。
4._init_(self)方法执行…
5.将对象的id赋值给变量。
class Person():
print('执行代码块中的代码1');
def __init__(self):
print('__init__已经执行了');
print('执行代码块中的代码2');
def say_hello(self,a):
print(self);
print(a);
print('你好,%s'%self.name);
p1 = Person();
# 执行代码块中的代码1
# 执行代码块中的代码2
# __init__已经执行了
- init会在对象创建以后立刻执行。
- init可以用来向新创建的对象中初始化属性。
class Person():
# name = '张三'; # 这个是在person类里面创建的name属性。
def __init__(self):
print(self);
self.name = '张三'; # 而这个self.name是在实例对象中创建的属性。
def say_hello(self,a):
print(self);
print(a);
print('你好,%s'%self.name);
p1 = Person();
p2 = Person();
print(p1.name);
print(p2.name);
# <__main__.Person object at 0x000001AE015C4B20>
# <__main__.Person object at 0x000001AE016070A0>
# 张三
# 张三
__init__参数,定义了几个,创建对象时必须传递几个,有一个是默认的self。
class Person():
# 调用类创建对象时,类后边的所有参数都会一次传递到init()中。
def __init__(self,name):
self.name = name;
def say_hello(self,a):
print(self);
print(a);
print('你好,%s'%self.name);
p1 = Person('张三');
p2 = Person('李四');
print(p1.name);
print(p2.name);
# 因为上面__init__需要name参数,因此,在创建p1时,我们必须传递一个name参数,否则报错。
# 张三
# 李四
类的基本结构,如下:
对象.属性 的方式来修改属性的值,不好!非常不安全。
6. 封装
- 封装指的是隐藏对象中一些不希望被外部所访问到的属性和方法。
如何获取(修改)对象中的属性?
- 需要提供一个getter和setter方法使外部可以访问到属性。
- getter 获取对象中的指定属性(get_属性名)。
- setter 用来设置对象的指定的属性(set_属性名)。
class Dog:
def __init__(self,name):
self.hidden_name = name;
def say_hello(self):
print('大家好,我是%s'%self.hidden_name);
def get_name(self):
# print('用户读取了属性');
return self.hidden_name;
def set_name(self,New_name):
# print('用户修改了属性');
self.hidden_name = New_name;
d = Dog('二哈');
d.say_hello();
print(d.get_name()); # 通过getter来查看属性值
d.set_name('金毛'); # 通过setter来改变属性值
print(d.get_name());
# 大家好,我是二哈
# 二哈
# 金毛
注意:向hidden_name这种只是改了一个名字,和使用__双下划线来操作隐藏属性是一样的都是通过改名字来操作的。
getter和setter的优缺点:
可以为对象的属性使用双下划线开头,__xxx,这是对象的隐藏属性。
- 隐藏属性只能在类的内部访问,无法通过对象访问。
- 其实隐藏属性只不过是Python自动为属性改了一个名字,实际上是将名字修改为了,_类名__属性名。例如:__name -> _Person__name。
class Person:
def __init__(self,name):
self.__name = name;
def get_name(self):
return self.__name;
def set_name(self,New_name):
self.__name = New_name;
p = Person('张三');
print(p.get_name());
p.set_name('李四');
print(p.get_name());
# print(p.__name); # __双下划线开头的属性是隐藏属性,无法通过对象访问。
print(p._Person__name); # 也是改名字。将名字修改为了,_类名__属性名。例如:__name -> _Person__name。
像上面改名字使用__双下划线操作的方式,我们一般不用。一般我们会将一些私有属性(不希望被外部访问的属性)以_(单下划线)开头。
- _(单下划线)开头依然还是可以修改了属性的,它的目的就是告诉我们不建议修改。
7. @property装饰器 和 @属性名.setter装饰器
其实,@property装饰器 和 @属性名.setter装饰器,就是像属性调用一样来操作,实际上还是方法调用。
- property装饰器,用来将一个的get方法,转换为对象的属性。
- 添加property装饰器以后,我们就可以调用属性一样来调用get方法。
- 注意使用property装饰的方法,必须和属性名一样的。
- setter方法的装饰器:@属性名.setter ,setter装饰器必须和property装饰器的get配合使用。
class Person:
def __init__(self,name):
self._name = name;
@property # property装饰器,用来将一个的get方法,转换为对象的属性。
# 添加property装饰器以后,我们就可以调用属性一样来调用get方法。
# 注意使用property装饰的方法,必须和属性名一样的。
def name(self):
print('get方法执行了~~');
return self._name;
# setter方法的装饰器:@属性名.setter
@name.setter
def name(self,name):
print('setter方法执行了~~');
self._name = name;
p = Person('张三');
print(p.name); # 不是p.name()这样调用,而是像调用属性一样。
p.name = '李四';
print(p.name);
8. 继承
继承就是对一个类进行扩展。
格式:
class 类名([父类]):
- 父类又叫超类,基类,super。
- 子类(衍生类)可以直接继承父类中的所有的属性和方法。
class Animal:
def run(self):
print('动物会跑~~');
def sleep(self):
print('动物睡觉~~');
def bark(self):
print('动物嚎叫~~');
# 父类又叫超类,基类,super。
# 子类(衍生类)可以直接继承父类中的所有的属性和方法。
class Dog(Animal):
def bark(self):
print('汪汪汪~~');
class Hashiqi(Dog): # 同样该继承也是可以调用Dog和Animal的方法。
def fangsha(self):
print('我是一只傻傻的哈士奇');
d = Dog();
d.run();
d.sleep();
d.bark();
# 检查一个对象,是否是类的实例
result1 = isinstance(d,Dog);
result2 = isinstance(d,Animal);
print(result1,result2); # 返回的都是True,也就是说d对象既是Dog,也是Animal。
- 在创建时,如果省略了父类,则默认父类为object。
- object是所有类的父类,所有类都继承自object。
- issubclass(a,b) # 判断a是否为b的子类,是返回True,否返回False。
- isinstance()用来检查一个对象是否是一个类的实例。
- 注意:所有的对象都是object的实例!
# Person不加括号,也是默认继承的object,可以通过issubclass()来判断验证。
class Person(object):
pass
print(issubclass(Person,object));
print(isinstance(print,object));
# True
# True
9. 方法重写(覆盖,override)
10. super
- 父类中的所有方法都会被子类继承,包括特殊方法__init__ 。
- 对于特殊方法,也是可以在子类中重写的。
- super() 可以用来获取当前类的父类,并且通过super() 返回对象调用父类方法时,不需要传递self。
- 通过super()返回对象调用父类方法时,不需要传递self。
class Animal:
def __init__(self,name):
self._name = name;
def run(self):
print('动物会跑~~');
def sleep(self):
print('动物睡觉~~');
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name;
class Dog(Animal):
def __init__(self,name,age):
# 通过super()返回对象调用父类方法时,不需要传递self。
super().__init__(name);
self._age = age;
def bark(self):
print('汪汪汪~~');
def run(self):
print('狗跑~~');
@property
def age(self):
return self._age
@age.setter
def age(self,age):
self._age = age;
d = Dog('二哈',18);
print(d.name,d.age);
d.name = '金毛';
d.age = 22;
print(d.name,d.age);
11. 多重继承
先记住一个隐藏属性:
- __bases__ ,bases 这个隐藏属性可以用来获取当前类的所有父类。
注意:开发中没有特殊情况,应该尽量避免使用多重继承,因为多重继承会让我们的代码过于复杂。
12. 多态
面向对象三大特征:封装,继承,多态。
__len__ ,len方法的隐藏属性:
class B:
def __init__(self,name):
self._name = name
# 定义了len,这样就可以调用len()方法来操作了
def __len__(self):
return 10;
@property
def name(self):
return self._name
@name.setter
def name(self,name):
self._name = name;
b = B('李四');
print(len(b)); # 10
13. 类中的属性和方法
理解好这几个名词:类属性,实例属性,实例方法,类方法。
类属性:
实例属性:
实例方法:
类方法 @classmethod :
- 类方法的第一个参数是cls,也会被自动传递,cls就是当前的类对象。
- 类方法和实例方法区别,实例方法第一个参数self,类方法第一个参数是cls(当前类对象),其他都差不多。
静态方法 @staticmethod :
- 在类中使用 @staticmethod 来修饰的方法属于静态方法。
- 静态方法不需要指定任何的默认参数,静态方法可以通过类和实例去调用。
- 静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类中的函数。
- 因此静态方法一般都是一些工具方法,和当前类无关。
class A(object):
# 类属性
count = 0
def __init__(self):
# 实例属性
self.name = '张三'
# 实例方法
def test(self):
print('这是个test方法~~',self)
# 类方法 @classmethod
# 类方法的第一个参数是cls,也会被自动传递,cls就是当前的类对象。
# 类方法和实例方法区别,实例方法第一个参数self,类方法第一个参数是cls(当前类对象)
# 类方法可以通过类和实例去调用。
@classmethod
def test_2(cls):
print('这是test_2方法~~,这是一个类方法',cls);
# 静态方法
# 在类中使用 @staticmethod 来修饰的方法属于静态方法。
# 静态方法不需要指定任何的默认参数,静态方法可以通过类和实例去调用。
# 静态方法,基本上是一个和当前类无关的方法,它只是一个保存到当前类中的函数。
# 因此静态方法一般都是一些工具方法,和当前类无关。
@staticmethod
def test_3():
print('test_3执行了~~');
a = A();
A.test_2(); # 通过类去调用
a.test_2(); # 通过实例调用
14. 垃圾回收
- 程序在运行过程中也会产生垃圾。
- 程序运行过程中产生的垃圾会影响到程序的运行性能,所以这些垃圾必须被及时清理。
- 什么是垃圾?在程序中没有被引用的对象就是垃圾。
- 格式:def __del__(self): 函数来调用垃圾回收
class A:
def __init__(self):
self.name = 'A类'
# del是一个特殊方法,它会在对象被垃圾回收前调用。
def __del__(self):
print('A()对象被删除了~~',self)
a = A();
b = a; # 如果有b为a,那么b也是一个A()对象,也是调用A的,就算a设置为了None,b依然还是指向A对象的。
# print(id(b),id(a),id(A()));
a = None # 这个时候将a设置为None,此时没有任何的变量对A()对象进行引用,它就变成了垃圾。
# del a;
# del b;
input('回车键退出'); # input回车后,程序也会自动删除,调用垃圾回收
15. 特殊方法(魔术方法)
特殊方法(魔术方法),以__开头结尾的。
__str__(self): 特殊方法
-
功能:当我们打印一个对象时,实际上打印的时对象中的特殊方法__str__()的返回值。
-
这个特殊方法会在尝试将对象转换为字符串的时候调用。
-
它的作用可以用来指定对象转换为字符串的结果。
class Person(object):
def __init__(self,name以上是关于python 人生苦短,我学Python的主要内容,如果未能解决你的问题,请参考以下文章