GVKun编程网logo

如何在Python中实现方法,类方法和静态方法?(python中静态方法和类方法的作用)

26

本文的目的是介绍如何在Python中实现方法,类方法和静态方法?的详细情况,特别关注python中静态方法和类方法的作用的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了

本文的目的是介绍如何在Python中实现方法,类方法和静态方法?的详细情况,特别关注python中静态方法和类方法的作用的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解如何在Python中实现方法,类方法和静态方法?的机会,同时也不会遗漏关于(转)python3:类方法,静态方法和实例方法以及应用场景、Python web(6)-静态方法和类方法的比较、Python 中的静态方法和类方法、Python 之路 - 面向对象 & 继承和多态 & 类属性和实例属性 & 类方法和静态方法的知识。

本文目录一览:

如何在Python中实现方法,类方法和静态方法?(python中静态方法和类方法的作用)

如何在Python中实现方法,类方法和静态方法?(python中静态方法和类方法的作用)

Python中的方法在什么时候获取get属性?—一旦在班级中定义了它们?为什么Python让我定义一个没有任何参数(甚至没有第一个self参数)的方法?

我知道如何使用classmethodstaticmethod,我知道它们是内置函数,但是这样装饰的函数会怎样?

本质上,我想知道类定义和类构造之间发生的“魔术”。

(转)python3:类方法,静态方法和实例方法以及应用场景

(转)python3:类方法,静态方法和实例方法以及应用场景

原文:https://blog.csdn.net/qq_34979346/article/details/83212716

1.实例方法
在编程里经常用的是实例方法,直接用实例去调用, 只要 方法里有self 就可以断定是实例方法,
如 def method_name(self,*argc). 先看下边代码如下:

class Date:
def __init__(self,year,month,day):
self.year=year
self.month=month
self.day=day
def __str__(self):
return ("{year}-{month}-{day}").format(year=self.year,month=self.month,day=self.day)

def yesterday(self):
self.day-=1

date=Date(2018,10,20)
print(date)

date.yesterday()

print(date)
#打印结果
2018-10-20
2018-10-19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
先说下 date.yesterday() ,实例直接调用方法名 ,会转化为 yesterday(date), 改变了实例的属性 day ,这也只是改变了实例的属性,并不会改变类的变量(这个在前面已经讲过了)。如果我就想在方法里改变类的变量怎么做呢?看下边的代码。

class Date:
day=10 #添加 类属性 day
def __init__(self,year,month,day):
self.year=year
self.month=month
self.day=day
def __str__(self):
return ("{year}-{month}-{day}").format(year=self.year,month=self.month,day=self.day)

def yesterday(Date):
Date.day-=1 #对类进行修改, 记住用的是Date.day ,如果是实例方法必须是 self.

date=Date(2018,10,20)
print(date)
#打印结果 实例传入 day =20, 就用实例的20,不会找 类的a=10
2018-10-20
Date.yesterday(Date)
print(date)
#打印结果 如下, 这个全部用的是类,跟self 没有关系,所以还是打印结果不变。
2018-10-20
print(Date.day)
#打印结果 调用修改类属性方法 生效。 如果self 没有day 这个属性,他一定去找类的变量 day, 这个可以自己尝试下。
9

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
上边的有点扯远了, 也算复习下 类变量和实例变量的关系。

2.静态方法
下边正式介绍 静态方法,我们之前想创造一个实例都是用 Date(2018,10,20),现在升级了, 假如我们想传递直接字符串的形式怎么办呢? 例如 “2018-01-01” or “2018/01/01" 如果直接传递百分之百错误。如果不用静态方法,我们首先用到的是,先把 这个字符串转化为 2018,01,01 这种形式再传递, 先看下边的代码就是这样形式。

year,month,day=tuple("2018-10-10".split("-"))
print(year,month,day)
#打印结果 转化成功, 再拿转化后的进行传值,
#2018 10 10
1
2
3
4
缺点是每次实例化都要调用这段代码,代码量自己想想, 有没有好的方法呢, 就用 静态方法可以解决这个问题,小白该说了,我直接定义个实例化方法不行了吗? 懂行的人会笑坏大牙,这里不做解释了,自己想想吧。
下边就开始用静态方法了 ,代码如下:

class Date:

def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

def __str__(self):
return ("{year}-{month}-{day}").format(year=self.year, month=self.month, day=self.day)

def yesterday(Date):
Date.day -= 1

@staticmethod # 用这个装饰器表明是静态方法,这个要注意。
def static(date_str):
year, month, day = tuple(date_str.split("-"))
return Date(int(year), int(month), int(day))


new_day=Date.static("2018-10-10") #由于静态方法不属于实例 所以调用的时候, 用类名.静态方法,这个要注意
print(new_day)


#打印结果 正好是咱们的预期结果。
2018-10-10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
以上用静态方法初始化数据,代码变短简洁 ,易读性提高。 假如我们要修改类名Date变成New_date,这个时候我们要同时修改所有调用的类名。比如上边的 return Date (int(year), int(month), int(day)),这个就是硬编码的形式。有没有办法不用修改,哈哈 当然有了。就是类方法能解决。

3.类方法
静态方法用 @staticmethod 标识, 类方法同样也有装饰器用 @classmethod ,实例方法传递的是self,类同样也是对象直接传递cls就行。

class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

def __str__(self):
return ("{year}-{month}-{day}").format(year=self.year, month=self.month, day=self.day)

def yesterday(Date):
Date.day -= 1

# @staticmethod
#def static(date_str):
# year, month, day = tuple(date_str.split("-"))
# return Date(int(year), int(month), int(day))

@classmethod #类方法的标识
def class_method(cls,date_str): # 这个cls只是表明类对象,是可以修改的,同样你改为self也是一样,叫cls为了提高可读性。
year, month, day = tuple(date_str.split("-"))
return cls(int(year), int(month), int(day)) #这个cls 和上边是一样的意思,这个就比静态方法好处就是会随便类名变化而变化。

new_day=Date.class_method("2018-10-10")
print(new_day)
#打印结果
2018-10-10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
我这样一比较,小伙伴该认为以后就没有用静态方法,反正类方法可以替代并且优越于他,存在就有合理的地方,下边我介绍静态方法的适合他的应用场景之一是校验传入值。请看下边的代码,是类方法和静态方法的结合。

class Date:

def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day

def __str__(self):
return ("{year}-{month}-{day}").format(year=self.year, month=self.month, day=self.day)

def yesterday(Date):
Date.day -= 1

@staticmethod #校验输入值类型和大小是否符合咱们的类型。
def var_str(date_str):
year, month, day = tuple(date_str.split("-"))
if 0 < int(year) and 0 < int(month) <= 12 and 0 < int(day) < 32:
return True
else:
return False

@classmethod
def class_method(cls, date_str):

if cls.var_str(date_str): #这里是调用静态方法,注意要用cls.静态方法,原理和实例方法中的self一样,自己可以试试,否则是不能读取的。
year, month, day = tuple(date_str.split("-"))
return cls(int(year), int(month), int(day))


new_day = Date.class_method("2018-10-10")
print(new_day)
# 打印结果
2018 - 10 - 10

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
总结下 为什么这样结合呢, 校验方法和初始化数据方法分开,代码的逻辑清晰, 就像前端和后端要分离一样的道理。 用的最多的是实例方法。

实例方法 用self标识,一般用实例调用, 静态方法标识是 @staticmethod用类名去调用,类方法优于静态方法解决了静态方法的类名的硬编码, 在不同的场景搭配不同方法为了达到代码的可读性简洁。

Python web(6)-静态方法和类方法的比较

Python web(6)-静态方法和类方法的比较

场景:

class MyClass:
    val1 = ''Value 1''
    def __init__(self):
        self.val2 = ''Value 2''

    @staticmethod
    def staticmd():
        print ''静态方法,无法访问val1和val2''

    @classmethod
    def classmd(cls):
        print ''类方法,类:'' + str(cls) + '',val1:'' + cls.val1 + '',无法访问val2的值''

结论:

静态方法:无法访问类属性、实例属性,相当于一个相对独立的方法,跟类其实没什么关系,
换个角度来讲,其实就是放在一个类的作用域里的函数而已。相当Java中的工具类
类成员方法:可以访问类属性,无法访问实例属性。
上述的变量val1,在类里是类变量,在实例中又是实例变量,所以容易混淆。 相当于Java中的静态方法

 

Python 中的静态方法和类方法

Python 中的静态方法和类方法

    昨天同事问我一个关于 Python 静态方法和类方法的区别,上网找了些资料整理一下:

@staticmethod 和 @classmethod 都是用来定义静态函数的,它们的相同点是都不用实例化类,可以直接用类名来调用其相关属性。不同点是,@classmethod 的第一个参数是 cls,因此可以访问类变量。@staticmethod 只是自身代码在类里面,对类的其它再无相关。一般情况下用 @classmethod,@staticmethod 只适用于不想定义全局函数的情况。

    下面是摘抄自 Python 核心编程第二版:
静态方法和类方法 
静态方法和类方法在 Python2.2 中引入。经典类及新式 (new-style) 类中都可以使用它。一对内
建函数被引入,用于将作为类定义的一部分的某一方法声明 “标记”(tag),“强制类型转换”(cast)
或者 “转换”(convert) 为这两种类型的方法之一。 
如果你有一定的 C++ 或者 Java 经验,静态方法和这些语言中的是一样的。它们仅是类中的函数 (不
需要实例)。事实上,在静态方法加入到 Python 之前,用户只能在全局名字空间中创建函数,作为
这种特性的替代实现 - 有时在这样的函数中使用类对象来操作类(或者是类属性)。使用模块函数
比使用静态类方法更加常见。 
回忆一下,通常的方法需要一个实例 (self) 作为第一个参数,并且对于(绑定的)方法调用来
说,self 是自动传递给这个方法的。而对于类方法而言,需要类而不是实例作为第一个参数,它是
由解释器传给方法。类不需要特别地命名,类似 self,不过很多人使用 cls 作为变量名字。 

staticmethod () 和 classmethod () 内建函数 
现在让我们看一下在经典类中创建静态方法和类方法的一些例子(你也可以把它们用在新式类
中): 
class TestStaticMethod: 
def foo(): 
print ''calling static method foo()'' 
foo = staticmethod(foo) 
class TestClassMethod: 
def foo(cls): 
print ''calling class method foo()'' 
print ''foo() is part of class:'', cls.__name__ 
foo = classmethod(foo) 
对应的内建函数被转换成它们相应的类型,并且重新赋值给了相同的变量名。如果没有调用这
两个函数,二者都会在 Python 编译器中产生错误,显示需要带 self 的常规方法声明。现在,我们
可以通过类或者实例调用这些函数.... 这没什么不同: 
>>> tsm = TestStaticMethod() 
>>> TestStaticMethod.foo() 
calling static method foo() 
>>> tsm.foo() 
calling static method foo() 
>>> 
>>> tcm = TestClassMethod() 
>>> TestClassMethod.foo() 
calling class method foo() 
foo() is part of class: TestClassMethod 
>>> tcm.foo() 
Edit By Vheavens 
Edit By Vheavens 
calling class method foo() 
foo() is part of class: TestClassMethod 

使用函数修饰符 
现在,看到像 foo=staticmethod (foo) 这样的代码会刺激一些程序员。很多人对这样一个没意义
的语法感到心烦,即使 van Rossum 曾指出过,它只是临时的,有待社区对些语义进行处理。在第 11
章 “函数” 的 11.3.6 节中,我们了解了函数修饰符,一种在 Python2.4 中加入的新特征。你可以用
它把一个函数应用到另个函数对象上,而且新函数对象依然绑定在原来的变量。我们正是需要它来
整理语法。通过使用 decorators,我们可以避免像上面那样的重新赋值: 
class TestStaticMethod: 
@staticmethod 
def foo(): 
print ''calling static method foo()'' 
class TestClassMethod: 
@classmethod 
def foo(cls): 
print ''calling class method foo()'' 
print ''foo() is part of class:'', cls.__na

Python 之路 - 面向对象 & 继承和多态 & 类属性和实例属性 & 类方法和静态方法

Python 之路 - 面向对象 & 继承和多态 & 类属性和实例属性 & 类方法和静态方法

一、面向对象

  编程方式

  面向过程:根据业务逻辑从上到下写垒代码

  函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可

  面向对象:对函数进行分类和封装,让开发 “更快更好更强…”

  什么是面向对象

  面向对象就不像面向过程那样按照功能划分模块了,它所关注的是软件系统有哪些参与者,把这些参与者称为对象,找出这些软件系统的参与者也就是对象之后,分析这些对象有哪些特征、哪些行为,以及对象之间的关系,所以说面向对象的开发核心是对象

  什么是类

  面向对象编程的两个重要的概念:类和对象

  类是对象的类型,具有相同属性和行为事物的统称。类是抽象的,在使用的时候通常会找到这个类的一个具体存在。

  什么是对象

  万物皆对象,对象拥有自己的特征和行为。

  类和对象的关系

  类是对象的类型,对象是类的实例。类是抽象的概念,而对象是一个你能够摸得着,看得到的实体。二者相辅相成,谁也离不开谁。

二、类的定义

  类由三部分组成

  类的名称:类型

  属性:对象的属性

  方法:对象的方法

  类定义:

  class 类名:

    属性列表

    方法列表

  __init__() 构造方法和 self

  __init__()是一个特殊的方法属于类的专有方法,被称为类的构造函数或初始化方法,方法的前面和后面都有两个下划线。   这是为了避免 Python 默认方法和普通方法发生名称的冲突。每当创建类的实例化对象的时候,__init__() 方法都会默认被运行。作用就是初始化已实例化后的对象。

  在方法定义中,第一个参数 self 是必不可少的。类的方法和普通的函数的区别就是 self,self 并不是 Python 的关键字,你完全可以用其他单词取代他,只是按照惯例和标准的规定,推荐使用 self。

''''''
    类定义
    class 类名():
        #类的文档说明
        属性
        方法
''''''
class person():
    ''''''
    这是一个人类
    ''''''

    country = ''中国'' #类属性
    #实例属性通过构造方法来声明
    #self不是关键字,代表的是当前对象(类似于this)
    def __init__(self,name,age,sex): #构造方法
        #构造方法不需要调用 在实例化的时候自动调用
        print(''我是构造方法,在实例化的时候调用'')
        self.name = name #通过self 创建实例属性 并且赋值
        self.age = age
        self.sex = sex

    #创建普通方法
    def getName(self):
         print(''我的名字叫:%s,我来自%s'' %(self.name,person.country))#在方法里面使用实例属性

#实例化对象
people01 = person(''joe'',12,''男'')
#这个people01 就要具有三个属性,并且可以使用getName方法

  类的属性分类

  类属性

  类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。如果需要用在函数中使用类名。类属性.

  实例属性

  实例变量:定义在方法中的变量,只作用于当前实例的类。

  类的属性的一些方法

  可以使用实例化对象名 +. 来访问对象的属性

  也可以使用以下函数的方式来访问属性

    getattr (obj, name [, default]) : 访问对象的属性

    hasattr (obj,name) : 检查是否存在一个属性

    setattr (obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性

    delattr (obj, name) : 删除属性

  注意:name 需要加单引号,obj 为实例化对象名称

#访问属性
# print(people01.name)#通过对象名.属性名 访问实例属性(对象属性)
# print(people01.age)
# print(people01.sex)

#通过内置方法访问对象属性
# print(getattr(people01,''name''))

# print(hasattr(people01,''name''))
#
# print(setattr(people01,''name'',''susan''))
# print(people01.name)
#
# delattr(people01,''name'')
# print(people01.name)

#通过对象调用实例方法
# people01.getName()

  内置类属性

  Python 内置类属性

  __dict__ : 类的属性(包含一个字典,由类的属性名:值组成) 实例化类名.__dict__

  __doc__ : 类的文档字符串 (类名.) 实例化类名.__doc__

  __name__: 类名,实现方式 类名.__name__

  __bases__ : 类的所有父类构成元素(包含了以个由所有父类组成的元组)  

''''''
    内置类属性
''''''
# print(people01.__dict__) #会将实例对象的属性和值通过字典的形式返回
#{''age'': 12, ''name'': ''joe'', ''sex'': ''男''}

# print(people01.__doc__) #查看类的文档说明
#    这是一个人类

# print(people01.__name__) #返回类名

# print(person.__bases__) #类的组成 (<class ''object''>,)

people02 = person(''susan'',32,''女'')
people02.getName()

  小结:

  类 (Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

  类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。

  数据成员:类变量或者实例变量 (方法中的变量) 用于处理类及其实例对象的相关的数据。

  方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。

  实例变量:定义在方法中的变量,只作用于当前实例的类。

  实例化:创建一个类的实例,类的具体对象。

  方法:类中定义的函数。

  对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

  __name__

  __name__: 如果是放在 Modules 模块中,就表示是模块的名字; 如果是放在 Classs 类中,就表示类的名字;

  __main__:模块,xxx.py 文件本身。被直接执行时,对应的模块名就是__main__了 可以在 if __name__ == “__main__”: 中添加你自己想要的,用于测试模块,演示模块用法等代码。 作为模块,被别的 Python 程序导入(import)时,模块名就是本身文件名 xxx 了。

  一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。

定义 name.py 文件

def a():
    print(''我是a方法'')

if __name__ == ''__main__'':
    a()

print(__name__) #__main__

输出:

  我是 a 方法
  __main__

定义 name2.py 文件

''''''
引入name.py文件
输出 name
''''''
import name

输出:name

练习:

''''''
1.餐馆:创建一个名为Restaurant的类,其方法__init__()设置两个属性:
restaurant_name 和 cuisine_type(烹饪)。
创建一个名为 describe_restaurant()方法和一个名为open_restaurant ()
方法,其中前者打印前述两项信息,而后者打印一条消息,指出餐馆正在营业。
根据这个类创建一个名为restaurant的实例,分别打印其两个属性,
再调用前述两个方法。

2.三家餐馆:根据你为完成练习1而编写的类创建三个实例,
并对每个实例调用方法 describe_restaurant()。

3.就餐人数:在为完成练习1而编写的程序中,添加一个名为number_served的属性,
并将其默认值设置为0。打印有多少人在这家餐馆就餐过,然后修改这个值并再次打印
它。
添加一个名为set_number_served()的方法,它让你能够设置就餐人数。
调用这个方法并向它传递一个值,然后再次打印这个值。
添加一个名为increment_number_served()的方法,它让你能够将就餐人数递增.
调用这个方法并向它传递一个这样的值:你认为这家餐馆每天可能接待的就餐人数。


''''''
class Restaurant():
    ''''''
        餐馆类
    ''''''
    def __init__(self,restaurant_name,cuisine_type,number_served = 0):
        #声明两个实例属性
        self.restaurant_name = restaurant_name #餐馆名字
        self.cuisine_type = cuisine_type       #菜系
        self.number_served = number_served

    def describe_restaurant(self):
        print(''名称:%s,菜系:%s''%(self.restaurant_name,self.cuisine_type))


    def open_restaurant(self):
        print(''欢迎光临%s,正在营业''%self.restaurant_name)


    #设置就餐人数
    def set_number_served(self,n):
        self.number_served = n  #通过传递的参数给实例属性赋值
        print(''当前就餐人数:%d''%self.number_served)

    #递增增加就餐人数
    def increment_number_served(self,n):
        for i in range(1,n+1):
            self.number_served += 1
            print(''当前就餐人数:%d''%self.number_served)

if __name__ == ''__main__'':
    #练习1.
    # restaurant = Restaurant(''金拱门'',''西餐'')
    #打印两个属性
    # print(restaurant.restaurant_name)
    # print(restaurant.cuisine_type)

    #调用两个方法
    # restaurant.describe_restaurant()
    # restaurant.open_restaurant()

    # 练习2. 创建三个实例
    # chuancai = Restaurant(''我家酸菜鱼'', ''川菜'')
    # chuancai.describe_restaurant()
    #
    # xiangcai = Restaurant(''沪上湘城'', ''湘菜'')
    # xiangcai.describe_restaurant()
    #
    # loulan = Restaurant(''楼兰'', ''新疆菜'')
    # loulan.describe_restaurant()

    #4.
    loulan = Restaurant(''楼兰'', ''新疆菜'')
    # print(''就餐人数:%d''%loulan.number_served)
    # loulan.number_served = 10  #通过对象名.属性名设置 属性值
    # print(''就餐人数:%d'' % loulan.number_served)
    loulan.set_number_served(40)
    loulan.increment_number_served(10)

  

''''''
    创建一个名为User的类,其中包含属性first_name和last_name ,
    还有用户简介通常会存储的其他属性。在User中定义一个名为describe_user()的方法
    他打印用户信息摘要;
    再定义一个名为greet_user()方法,他向用户发出个性化的问候。
    创建多个表示不同用户的实例,并对每个实例都调用上述两个方法
''''''
''''''
  2.尝试登录次数:在为完成练习3而编写的User类中,添加一个名为login_attempts的属性。
  编写一个名为increment_login_attempts()的方法,它将属性 login_attempts的值加 1。
  再编写一个名为reset_login_attempts()方法,它将属性login_attempts的值重置为0。 
  根据User类创建一个实例,再调用方法increment_login_attempts()多次。
  打印属性login_attempts的值,确认它被正确地递增;然后,调用方法reset_login_attempts(),
  并再次打印属性login_attempts的值,确认它被重置为0。
''''''

class User():
    ''''''
    用户类
    ''''''
    def __init__(self,first_name,last_name,age,sex,phone,login_attempts = 0):
        self.first_name = first_name
        self.last_name = last_name
        self.age = age
        self.sex = sex
        self.phone = phone
        self.login_attempts = login_attempts

    #查看用户信息
    def describe_user(self):
        print(''大家好我叫%s %s,我今年%d岁,我的电话是%s'' %(self.first_name,self.last_name,self.age,self.phone))

    #个性化问候
    def greet_user(self):
        print(''尊敬的%s,恭喜你中了五百万''%self.first_name)

    #增加登录次数
    def increment_login_attempts(self):
        self.login_attempts += 1
        print(''当前登录次数为%d''%self.login_attempts)

    #重置登录次数
    def reset_login_attempts(self):
        self.login_attempts = 0
        print(''当前登录次数为%d'' % self.login_attempts)

if __name__ == ''__main__'':

    joe = User(''joe'',''black'',19,''男'',''15768476789'')
    joe.describe_user()
    joe.greet_user()

    joe.increment_login_attempts()
    joe.increment_login_attempts()
    joe.increment_login_attempts()

    joe.reset_login_attempts()

三、继承和多态

  继承:

  在现实生活中,继承一般指的是子女继承父辈的财产。那么在程序中,继承描述的是事物之间的所属关系,例如猫和狗都属于动物,程序中可以描述为猫和狗都继承自动物。同理,波斯猫和家猫都继承自猫。而斑点狗,泰迪都继承之狗。程序中当我们定义一个 class 的时候,可以从某个现有的 class 继承,新的 class 称之为子类(Subclass),而被继承的 class 称之为基类、父类或超类。子类继承了其父类的所有属性和方法,同时还可以定义自己的属性和方法。

  子类的__init__()

class Animal():
    def __init__(self,name,food):
        self.name = name
        self.food = food

    def eat(self):
        print(''%s爱吃%s''%(self.name,self.food))

#声明一个子类继承Animal
class Dog(Animal):
    def __init__(self,name,food,drink):
        #加载父类的构造方法
        super(Dog,self).__init__(name,food)
        # Animal.__init__(name,food) #报错
        self.drink = drink #子类自己的属性

    #子类自己的方法
    def drinks(self):
        print(''%s爱喝%s''%(self.name,self.drink))

class Cat(Animal):
    def __init__(self,name,food,drink):
        #加载父类的构造方法
        super(Cat,self).__init__(name,food)
        # Animal.__init__(name,food) #报错
        self.drink = drink #子类自己的属性

    #子类自己的方法
    def drinks(self):
        print(''%s爱喝%s''%(self.name,self.drink))

    #重写父类的eat方法
    def eat(self):
        print(''%s特别爱吃%s''% (self.name, self.food))


dog1 = Dog(''金毛'',''骨头'',''可乐'')
dog1.eat()
dog1.drinks()

dog1 = Cat(''波斯猫'',''秋刀鱼'',''雪碧'')
dog1.eat()
dog1.drinks()

  多继承

  Python 中多继承的语法格式如下:

  class DerivedClassName(Base1, Base2, Base3):

  <statement-1>

  .

  .

  .

  <statement-N>

  注意:圆括号中父类的顺序,如果继承的父类中有相同的方法名,而在子类中使用时未指定,python 将从左至右查找父类中是否包含方法。

 

class A():
    def a(self):
        print(''我是A里面的a方法'')

class B():
    def b(self):
        print(''我是B里面的b方法'')

    def a(self):
        print(''我是B里面的a方法'')


class C():
    def c(self):
        print(''我是C里面的C方法'')

class D(A,B,C):
    def d(self):
        print(''我是D里面的d方法'')

dd = D()
dd.d() #调用自己的方法
dd.c()
dd.a()

  重新

class Animal():
    def __init__(self,name,food):
        self.name = name
        self.food = food

    def eat(self):
        print(''%s爱吃%s''%(self.name,self.food))

#声明一个子类继承Animal
class Dog(Animal):
    def __init__(self,name,food,drink):
        #加载父类的构造方法
        super(Dog,self).__init__(name,food)
        # Animal.__init__(name,food) #报错
        self.drink = drink #子类自己的属性

    #子类自己的方法
    def drinks(self):
        print(''%s爱喝%s''%(self.name,self.drink))

class Cat(Animal):
    def __init__(self,name,food,drink):
        #加载父类的构造方法
        super(Cat,self).__init__(name,food)
        # Animal.__init__(name,food) #报错
        self.drink = drink #子类自己的属性

    #子类自己的方法
    def drinks(self):
        print(''%s爱喝%s''%(self.name,self.drink))

    #重写父类的eat方法
    def eat(self):
        print(''%s特别爱吃%s''% (self.name, self.food))


dog1 = Dog(''金毛'',''骨头'',''可乐'')
dog1.eat()
dog1.drinks()

dog1 = Cat(''波斯猫'',''秋刀鱼'',''雪碧'')
dog1.eat()
dog1.drinks()

  练习

 

''''''
冰淇淋小店:冰其淋小店是一种特殊的餐馆。
编写一个名为IceCreamStand的类,让它继承你为完成练习1或练习4而编写的Restaurant类。
这两个版本Restaurant类都可以,挑选你更喜欢的那个即可。
添加一个名为flavors的属性,用于存储一个由各种口味的冰淇淋组成的列表。
编写一个显示这些冰淇淋的方法。创建一IceCreamStand实例,并调用这个方法。
''''''
from Restaurant import Restaurant

class IceCreamStand(Restaurant):
    #加载父类方法  并且增加新的属性
    def __init__(self,restaurant_name,cuisine_type,flavors,number_served = 0):
        super(IceCreamStand,self).__init__(restaurant_name,cuisine_type,number_served = 0)
        self.flavors = flavors

    def get_info(self):
        print(''这家冰激凌小店的名字是%s,他的特色是%s,冰激凌的口味是%s''%(self.restaurant_name,self.cuisine_type,self.flavors))

queen = IceCreamStand(''冰雪换后'',''手工制作冰激凌'',''草莓味'',''巧克力味'',''奶油味'')
queen.get_info()

 

  

 

''''''
    管理员:管理员是一种特殊的用户。
    编写一个名为Admin的类,让它继承你为完成练习3或练习5而编写的User类。
    添加一个名为privileges的属性,用于存储一个由字符串(如“can add post”、
    “can delete post”、“can ban user”等)组成的列表。
    编写一个名为show_privileges()的方法,它显示管理员的权限,创建一个Admin实例,
    并调用这个方法。

''''''

from User import User

class Admin(User):
    privileges = [''can add post'',''can delete post'',''can ban user'']
    def __init__(self,first_name,last_name,age,sex,phone,login_attempts = 0):
        super(Admin,self).__init__(first_name,last_name,age,sex,phone,login_attempts = 0)

    def show_privileges(self):
        print(''管理员:%s%s具有以下权限。''%(self.first_name,self.last_name))
        for i in Admin.privileges:
            print(i)

admin1 = Admin(''susan'',18,''女'',''1243778494'')
admin1.show_privileges()

  四、类属性和实例属性

  属性

  尽量把需要用户传入的属性作为实例属性,而把同类都一样的属性作为类属性。实例属性在每创造一个类是都会初始化一遍,不同的实例的实例属性可能不同,不同实例的类属性都相同。

  1:实例属性:     

  在__init__(self,...) 中初始化     

  内部调用时都需要加上 self.     

  外部调用时用 “对象名。属性名” 调用

  2: 类属性:     

  在__init__() 里初始化     

  在内部用 classname. 类属性名调用     

  外部既可以用 classname. 类属性名又可以用 instancename. 类属性名来调用

  3:私有属性:     

  双下划线__开头:外部不可通过 “对象名。属性名” 来访问或者更改实际将其转化为了 “_类名__属性名”

  __foo__: 定义的是特殊方法,类似 __init__() 之类的。

  _foo: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问 (创建的实例可以访问),不能用于 from module import *

  __foo: 双下划线的表示的是私有类型 (private) 的变量,只能是允许这个类本身进行访问了。

class person():
    ''''''
    这是一个人类
    ''''''

    country = ''中国'' #类属性
    #实例属性通过构造方法来声明
    #self不是关键字,代表的是当前对象(类似于this)
    def __init__(self,name,age,sex,address): #构造方法
        #构造方法不需要调用 在实例化的时候自动调用
        print(''我是构造方法,在实例化的时候调用'')
        self.name = name #通过self 创建实例属性 并且赋值
        self.age = age
        self.sex = sex
        self.__address = address #私有属性

    #创建普通方法
    def getName(self):
        #私有属性在类里面使用可以正常使用
         print(''我的名字叫:%s,我来自%s,我住在%s'' %(self.name,person.country,self.__address))#在方法里面使用实例属性

    #外部要修改私有属性,预留一个接口去访问或者修改私有属性  这是正确的打开方式
    def getAddress(self,pwd):
        if pwd == ''123'':
            return self.__address
        else:
            return ''权限不够''

#实例化对象
people01 = person(''joe'',12,''男'',''上海'')
people01.getName()
#这个people01 就要具有三个属性,并且可以使用getName方法

#通过对象名.属性名访问私有属性
# print(people01.__address) #外部无法使用这种方式访问

#推荐使用
print(people01.getAddress(''123''))

#强制访问 不要使用
print(people01._person__address)

people01.__address = ''北京'' #看上去好像改了  其实没有  你给当前对象声明了一个新属性
print(people01.__address)

print(people01.getAddress(''123''))

五、访问限制

  私有类属性

  私有对象属性 为了保护属性不被随意修改和访问,可以将属性定义为私有属性

  如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,

  在 Python 中,实例变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问. 

  注意:

  1. 设置为私有属性不能直接通过对象访问属性,但是可以通过 “实例化对象名._类名__属性名” 直接进行访问。但是不建议这样操作。不同版本的 Python 解释器可能会把 “__属性名” 改成不同的变量名。总的来说就是,Python 本身没有任何机制阻止你干坏事,一切全靠自觉。

  2. 通过 “对象名.__属性名” 直接修改私有属性。 表面上看好像修改了其实并没有,因为 Python 解释器已经将对象内部的属性名解释成 “_类名__属性名”。如果在外部修改相当于另外声明一个属性。类属性可以直接修改通过类名._类名__属性名 =(可通过类方法定义) 

六、类方法和静态方法

  类方法与静态方法

  1:普通方法:     

    def fun_name(self,...):       

    pass     

    外部用实例调用

  2:静态方法:通过装饰器 @staticmethod 装饰       

    不能访问实例属性

    参数不能传入 self       

    与类相关但是不依赖类与实例的方法

  3: 类方法:@classmethod      

    不能访问实例属性 参数必须传入 cls      

    必须传入 cls 参数(即代表了此类对象 ----- 区别 ------self 代表实例对象),并且用此来调用类属性:cls. 类属性名

  静态方法与类方法都可以通过类或者实例来调用。其两个的特点都是不能够调用实例属性

  静态方法不需要接收参数,使用类名。类属性

class person():
    ''''''
    这是一个人类
    ''''''

    country = ''中国'' #类属性
    #实例属性通过构造方法来声明
    #self不是关键字,代表的是当前对象(类似于this)
    def __init__(self,name,age,sex,address): #构造方法
        #构造方法不需要调用 在实例化的时候自动调用
        print(''我是构造方法,在实例化的时候调用'')
        self.name = name #通过self 创建实例属性 并且赋值
        self.age = age
        self.sex = sex
        self.__address = address #私有属性

    #创建普通方法
    def getName(self):
        #私有属性在类里面使用可以正常使用
         print(''我的名字叫:%s,我来自%s,我住在%s'' %(self.name,person.country,self.__address))#在方法里面使用实例属性

    #创建一个静态方法
    @staticmethod
    def aa(): #不需要传递实例
        #静态方法不能访问实例属性
        #静态方法只能访问类属性
        print(''我的名字叫:%s'' % person.country)

    #类方法
    @classmethod
    def bb(cls):   #class 也不是关键字
        # 类方法不能访问实例属性
        print(''我的名字叫:%s'' % cls.country) #使用cls.类属性
        print(''我的名字叫:%s'' % person.country)

#实例化对象
people01 = person(''joe'',12,''男'',''上海'')
#通过对象来调用静态方法
people01.aa()
#通过对象来调用类方法
people01.bb()

#静态方法和类方法的调用  推荐使用类名的方式去调用
#通过类名来调用静态方法
person.aa()
#通过类名来调用类方法
person.bb()

  

''''''
练习:亡者农药小游戏

1、创建三个游戏人物,分别是:
属性:
    名字:name,定位:category,血量:Output技能:Skill
英雄:
    铠,战士,血量:1000 技能:极刃风暴
    王昭君,法师 ,血量:1000 技能:凛冬将至
    阿轲,刺客,血量:1000 技能:瞬华

2、游戏场景,分别:

偷红buff,释放技能偷到红buff消耗血量300
solo战斗,一血,消耗血量500
补血,加血200

''''''
class hero():

    #定义属性
    def __init__(self,name,category,skill,output = 0,score = 0):
        self.name = name
        self.category = category
        self.skill = skill
        self.output = output
        self.score = score

    #战队场景1:偷红buff
    def red_buff(self):
        self.output -= 300
        print(''%s%s到对面野区偷红buff,消耗血量300'')

    #战斗场景2:solo战斗
    def solo(self,n = 1):
        self.output -= 500
        if self.output < 0:
            print(''%s%s,送了一个人头,血染王者峡谷''%(self.category,self.name))
        else:
            if self.score == 0:
                self.score += n
                print(''%s%s战斗拿到一血,血量消耗500''%(self.category,self.name))
            else:
                self.score += n
                print(''%s%s solo战斗收割%d个人头,血量消耗500''%(self.category,self.name,n))
    #场景三:加血
    def add_xue(self):
        self.output += 200
        print(''%s%s被辅助及时奶了一口,加血200''%(self.category,self.name))
    #查看英雄信息
    def getInfo(self):
        if self.output <= 0:
            print(''%s%s 正在复活。拿到%d个人头''%(self.category,self.name,self.score))
        else:
            print(''%s%s超神了!血量还有%d,拿到%d个人头''%(self.category,self.name,self.output,self.score))

#实例化对象
kai = hero(''铠'',''战士'',''极刃风暴'')

#操作
kai.red_buff()
kai.getInfo()
kai.solo()
kai.getInfo()
kai.add_xue()
kai.getInfo()
kai.solo()
kai.getInfo()

  

''''''
模拟一个简单的银行进行业务办理的类

类:
    创建一个银行类
属性:
    一个属于银行的类属性
        用来存储所用银行的开户信息,包含卡号、密码、用户名、余额
        (外界不能随意访问和修改。开户时要进行卡号验证,查看卡号是否已经存在)

    每个对象拥有
        卡号、密码、用户名、余额
        (外界不能随意访问和更改)

方法:
    银行类拥有
        查看本银行的开户总数
        查看所有用户的个人信息(包含卡号、密码、用户名、余额)
    每个对象拥有
        实例化对象的时候传入相关参数
            初始化对象及类属性
        取钱(需要卡号和密码验证)
            通过验证卡号和密码对个人的余额进行操作,如果取钱大于余额,返回余额不足
        存钱(需要卡号和密码验证)
            通过验证卡号和密码对个人的余额进行操作,返回操作成功
        查看个人详细信息(需要卡号密码验证)
            返回个人的卡号,用户名,余额信息
''''''

class Bank():
    #一个属于银行的类属性
    __Users = {}

    #每个对象拥有 卡号 密码 用户名 余额
    def __init__(self,CardId,pwd,name,balance):
        if CardId not in Bank.__Users:
            Bank.__Users[CardId] = {''pwd'':pwd,''Username'':name,''Balance'':balance}
            self.__CardId = CardId
            self.__pwd = pwd
            self.__name = name
            self.__balance = balance

    #查看本银行的开户总数
    @classmethod
    def nums(cls):
         print(''当前用户数%d''%(len(cls.__Users)))

    #查看所有用户的个人信息(包含卡号、密码、用户名、余额)
    @classmethod
    def get_Users(cls):
        for key,val in cls.__Users.items():
            print(''卡号:%s \n用户名:%s \n密码:%d \n 余额:%d''%(key,val[''Username''],val[''pwd''],val[''Balance'']))
            print()

     #验证方法
    @staticmethod
    def check_User(CardId,pwd):
        if (CardId in Bank.__Users) and (pwd == Bank.__Users[CardId][''pwd'']):
            return True
        else:
            return False

    #验证金额
    @staticmethod
    def check_money(money):
        if isinstance(money,int):
            return True
        else:
            return False

    #取钱(需要卡号和密码验证)
    def q_money(self,CardId,pwd,money):
        if Bank.check_User(CardId,pwd):
            #开始取钱
            if Bank.check_money(money):
                if Bank.__Users[CardId][''Balance''] >= money:
                   Bank.__Users[CardId][''Balance''] -= money
                   print(''当前卡号%s,当前取款金额%d,当前余额%d''%(CardId,money,Bank.__Users[CardId][''Balance'']))
                else:
                    print(''余额不足'')
            else:
                print(''您输入的金额有误'')
        else:
            print(''卡号或者密码有误'')

    #存钱(需要卡号和密码验证)
    def c_money(self,CardId,pwd,money):
        if Bank.check_User(CardId,pwd):
            #开始取钱
            if Bank.check_money(money):
                Bank.__Users[CardId][''Balance''] += money
                print(''当前卡号%s,当前存款金额%d,当前余额%d''%(CardId,money,Bank.__Users[CardId][''Balance'']))
            else:
                print(''您输入的金额有误'')
        else:
            print(''卡号或者密码有误'')

    #查看个人详细信息
    def getInfo(self,CardId,pwd):
        if Bank.check_User(CardId, pwd):
            print(''当前卡号%s,当前用户名%s,当前余额%d'' %(CardId, Bank.__Users[CardId][''Username''], Bank.__Users[CardId][''Balance'']))
        else:
            print(''卡号或者密码有误'')

joe = Bank(''1001'',111111,''joe'',100)
joe2 = Bank(''1001'',111111,''joe'',100)
Bank.nums()
print(''_''*50)
Bank.get_Users()
print(''_''*50)
joe.c_money(''1001'',111111,500)
print(''_''*50)
joe.q_money(''1001'',111111,300)
print(''_''*50)
joe.getInfo(''1001'',111111)

  

 

今天的关于如何在Python中实现方法,类方法和静态方法?python中静态方法和类方法的作用的分享已经结束,谢谢您的关注,如果想了解更多关于(转)python3:类方法,静态方法和实例方法以及应用场景、Python web(6)-静态方法和类方法的比较、Python 中的静态方法和类方法、Python 之路 - 面向对象 & 继承和多态 & 类属性和实例属性 & 类方法和静态方法的相关知识,请在本站进行查询。

本文标签: