1. 可变参数*Args
和**Kwargs
https://www.scaler.com/topics/python/args-and-kwargs-in-python/
*args
代表的是一组无关键字的可变参数值。**kwargs
表示的是一组可变键值对,类似字典参数。当对程序的输入参数不可预知或者扩展性要求很高时,选择可变参数是不错的主意。
*
的用法
def multiplyNumbers(*numbers):
product = 1
for n in numbers:
product *= n
return product
def args_output(*args):
for arg in args:
print(arg)
print("product:", multiplyNumbers(4, 4, 4, 4, 4, 4))
args_output(1, "hello", 3.14)
**
的用法
def whatTechTheyUse(**kwargs):
result = []
for key, value in kwargs.items():
# result.append("{} uses {}".format(key, value))
result.append("%s uses %s" % (key, value))
return result
print(whatTechTheyUse(Google='Angular', Facebook='react', Microsoft='.NET'))
*
和**
的拆包操作
Unpacking operators are used to unpack the variables from iterable data types like lists, tuples, and dictionaries.
A single asterisk() is used on any iterable given by Python.
The double asterisk(*) is used to iterate over dictionaries.
carCompany = ['Audi','BMW','Lamborghini']
print(*carCompany)
techStackOne = {"React": "Facebook", "Angular" : "Google", "dotNET" : "Microsoft"}
techStackTwo = {"dotNET" : "Microsoft1"}
mergedStack = {**techStackOne, **techStackTwo}
print(mergedStack)
2. property
属性用法
https://www.liaoxuefeng.com/wiki/1016959663602400/1017502538658208
在python中如果直接通过公有变量的方式把参数对外开放,则调用者可以随便修改参数值。如果通过类似java的get,set方法,则又略显复杂。在python中使用property可以兼容两者的功能,读取值的时候实际使用的是get方法,赋值的时候调用的是set方法。
class Student(object):
def get_score(self):
return self._score
def set_score(self, value):
if not isinstance(value, int):
raise ValueError("score must be an integer!")
if value < 0 or value > 100:
raise ValueError("score must between 0 ~ 100!")
self._score = value
def del_score(self):
del self._score
score = property(get_score, set_score, del_score)
student = Student()
student.score = 99
print(student.score)
student.score = 102
可以使用装饰器(java中为注解)简化
class Student(object):
@property
def score(self):
return self._score
# 这里的score要和带有@property注解的方法名对应
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError("score must be an integer!")
if value < 0 or value > 100:
raise ValueError("score must between 0 ~ 100!")
self._score = value
@score.deleter
def del_score(self):
del self._score
# score = property(get_score, set_score, del_score)
student = Student()
student.score = 99
print(student.score)
student.score = 102
也可以通过下面的方式自定义(描述符)
class Name:
def __get__(self, obj, cls=None):
pwd = input('请输入获取密码')
if pwd == '123':
return obj._name
else:
print('密码不正确,获取失败')
def __set__(self, obj, value):
pwd = input('请输入设置密码')
if pwd == '321':
obj._name = value
print('设置成功')
else:
print('密码不正确,设置失败')
class Student:
name = Name()
s = Student()
s.name = '小明'
print(s.name)
3. from __future__ import *
的作用
https://blog.csdn.net/zzc15806/article/details/81133045
这样的做法的作用就是将新版本的特性引进当前版本中,也就是说我们可以在当前版本使用新版本的一些特性。主要是为了版本兼容性,python中有个six库是专门用来处理版本兼容问题的。
from __future__ import (absolute_import, division, print_function,
unicode_literals)
# 兼容python2.x
print("hello world")
# 在python2.x版本中值为2,有了上面的导入之后,值和python3.x版本一致都为2.5
print(5/2)
4. 魔法方法 :__getitem__ 、 __len__、__setitem__
等的使用
https://www.jianshu.com/p/cca8e8834066
在Python中,如果我们想实现创建类似于序列和映射的类(可以迭代以及通过[下标]返回元素),可以通过重写魔法方法getitem、setitem、delitem、len方法去模拟。当然有很多其他魔法方法,比如
__cmp__(self, other),__add__(self, other)
,参考(https://pyzh.readthedocs.io/en/latest/python-magic-methods-guide.html):,其作用类似于C++的操作符重载。
魔术方法的作用:
getitem(self,key):返回键对应的值。
setitem(self,key,value):设置给定键的值
delitem(self,key):删除给定键对应的元素。
len():返回元素的数量
import collections
Card = collections.namedtuple("Card", ["rank", "suit"])
# 也可以使用一个类来定义Card
# class Card:
# def __init__(self,rank,suit):
# self.rank = rank
# self.suit = suit
class Puke:
ranks = [str(n) for n in range(2, 11)] + list("JQKA")
suits = "黑桃 方块 梅花 红心".split()
def __init__(self):
self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]
def __len__(self):
return len(self._cards)
def __getitem__(self, item):
return self._cards[item]
def __setitem__(self, key, value):
print(key, value)
self._cards[key] = value
pk = Puke()
print(len(pk))
print(pk[2:6])
print(pk[12::13])
5. 元类
https://www.geeksforgeeks.org/how-to-create-an-instance-of-a-metaclass-that-run-on-both-python2-and-python3/
https://www.zhihu.com/column/c_1604522311041966081
https://www.liaoxuefeng.com/discuss/969955749132672/1195234549018496
元类是用来动态生产功能类的类,是类验证的高效工具,防止子类继承某些类功能,动态生成类。
from typing import Any
class NoInstance(type):
# 类实例化
def __call__(self, *args, **kwargs):
if len(args) == 0 or args[0] != "factory":
raise TypeError("Can't instantiate directly")
# return super().__call__(*args, **kwargs)
return super().__call__(*(), **kwargs)
class Last_of_us(metaclass= NoInstance):
def play(self):
print("the Last Of Us is really funny")
class Uncharted(metaclass= NoInstance):
def play(self):
print("the Uncharted is really funny")
class PSGame(metaclass= NoInstance):
def play(self):
print("PS has many games")
class GameFactory:
games = {"last_of_us": Last_of_us, "uncharted": Uncharted}
def __new__(cls, name):
if name in cls.games:
return cls.games[name]("factory")
else:
return PSGame()
uncharted = GameFactory("uncharted")
uncharted.play()
last_of_us = GameFactory("last_of_us")
last_of_us.play()
psgame = GameFactory("else")
psgame.play()